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-вопросе.