Moq: Определение возвращаемых значений как часть ожиданий

Я новичок в Moq и изучаю.

Мне нужно проверить, что метод возвращает ожидаемое значение. Я собрал примерный пример, чтобы объяснить мою проблему. Это терпит неудачу:

"ArgumentException: выражение не является вызовом метода: c = > (c.DoSomething(" Jo "," Blog ", 1) =" OK ")"

Вы можете исправить то, что я делаю неправильно?

[TestFixtureAttribute, CategoryAttribute("Customer")]
public class Can_test_a_customer
{
    [TestAttribute]
    public void Can_do_something()
    {
        var customerMock = new Mock<ICustomer>();

        customerMock.Setup(c => c.DoSomething("Jo", "Blog", 1)).Returns("OK");

        customerMock.Verify(c => c.DoSomething("Jo", "Blog", 1)=="OK");
    }
}

public interface ICustomer
{
    string DoSomething(string name, string surname, int age);
}

public class Customer : ICustomer
{
    public string DoSomething(string name, string surname, int age)
    {
        return "OK";
    }
}

В двух словах: если бы я хотел протестировать метод, подобный приведенному выше, и я знаю, что я ожидаю "ОК", как бы написать его с помощью Moq?

Спасибо за любые предложения.

Ответы

Ответ 1

  • Вам нужен тестовый объект, который взаимодействует с макетными объектами (если вы не пишете тест для ученика для Moq.) Я написал простой ниже
  • Вы настраиваете ожидания на макет объекта, указав точные аргументы (строго - если вы хотите, конечно, используйте Is.Any<string>, чтобы принять любую строку) и укажите возвращаемые значения, если какой-либо
  • Ваш тестовый объект (как часть шага действия теста) вызовет ваш макет
  • Вы утверждаете, что испытуемый ведет себя по мере необходимости. Возвращаемое значение из методов макета будет использоваться испытуемым субъектом - проверьте его через открытый интерфейс тестового объекта.
  • Вы также проверяете, что все ожидания, которые вы указали, были выполнены - все методы, которые вы ожидали назвать, на самом деле вызывались.

.

[TestFixture]
public class Can_test_a_customer
{
  [Test]
  public void Can_do_something()
  {
    //arrange
    var customerMock = new Moq.Mock<ICustomer>();
    customerMock.Setup(c => c.DoSomething( Moq.It.Is<string>(name => name == "Jo"),
         Moq.It.Is<string>(surname => surname == "Blog"),
         Moq.It.Is<int>(age => age == 1)))
       .Returns("OK");

    //act
    var result = TestSubject.QueryCustomer(customerMock.Object);

    //assert
    Assert.AreEqual("OK", result, "Should have got an 'OK' from the customer");
    customerMock.VerifyAll();
  }
}

class TestSubject
{
  public static string QueryCustomer(ICustomer customer)
  {
    return customer.DoSomething("Jo", "Blog", 1);
  }
}

Ответ 2

Mock<T>.Verify не возвращает значение, возвращаемое вызовом метода, поэтому вы не можете просто сравнить его с ожидаемым значением с помощью "==".

На самом деле существует отсутствие перегрузки Verify, которая возвращает что-либо, потому что вам никогда не нужно проверять, что метод издевательства возвращает определенное значение, В конце концов, вы несете ответственность за настройку, чтобы вернуть это значение в первую очередь! Возвращаемые значения издевающихся методов должны использоваться кодом, который вы тестируете, - вы не тестируете mocks.

Используйте "Проверить", чтобы подтвердить, что метод был вызван с аргументами, которые вы ожидали, или что для свойства было назначено значение, которое вы ожидали. Возвращаемые значения издевающихся методов и свойств не важны к моменту перехода на фазу "assert" вашего теста.

Ответ 3

Вы делаете то же самое, что делал этот парень здесь: Как проверить другой метод в классе, был вызван с использованием Moq

Вы издеваетесь над тем, что вы тестируете. Это не имеет смысла. Использование Mocks для изоляции. Тест Can_Do_Something будет всегда проходить. Не важно что. Это не очень хороший тест.

Познакомьтесь более подробно с тестом Gishu или тестом, которые я предложил в связанном SO-вопросе.