#c# #nunit #moq
#c# #nunit #moq
Вопрос:
Я разрабатываю тесты для приложения. Существует метод, который имеет params
массив в качестве параметра. Я настроил метод с использованием Moq, но когда я запускаю тест, возвращаемое значение метода равно null, что означает, что он не издевается.
Вот пример кода:
public interface ITicketManager {
string GetFirstTicketInQueueIfMatches(params string[] ticketsToMatch);
}
public class TicketManager : ITicketManager {
private Queue<string> ticketQueue = new Queue<string>();
public string GetFirstTicketInQueueIfMatches(params string[] ticketsToMatch) {
var firstQueuedTicket = ticketQueue.Peek();
var firstQueuedTicketMatchesAnyOfRequested = ticketsToMatch.Any(t => t == firstQueuedTicket);
if(firstQueuedTicketMatchesAnyOfRequested)
return firstQueuedTicket;
return null;
}
}
Макет кода выглядит следующим образом:
var mock = new Mock<ITicketManager>();
mock.Setup(m => m.GetFirstTicketInQueueIfMatches(It.IsAny<string>()))
.Returns(p => {
if(p.Contains("A"))
return "A";
return null;
});
Почему он никогда не попадает в издевательский метод?
Ответ №1:
Вы пытаетесь вызвать метод, принимающий одну строку, а не массив. Имейте в виду, что именно компилятор C # обрабатывает эту params
часть, преобразуя вызывающий код, который просто указывает отдельные значения, в вызов, передаваемый в массиве. Что касается самого метода, то он просто получает массив — и это то, над чем вы издеваетесь.
Компилятор фактически превращает ваш код в:
mock.Setup(m => m.GetFirstTicketInQueueIfMatches
(new string[] { It.IsAny<string>() }))
это не то, что вы хотите.
Вы должны использовать:
mock.Setup(m => m.GetFirstTicketInQueueIfMatches(It.IsAny<string[]>()))
Если вам нужно убедиться, что ему присваивается только одно значение, вам нужно будет сделать это так же, как и для параметра, отличного от params.
По сути, params
это имеет значение только для компилятора C #, а не для moq
.
Комментарии:
1. @DiegoAC: Ну, у вас все равно есть условный возврат
null
. Вы пробовали заставить его возвращать «Foo» вместо этого, еслиp
не содержит"A"
? Таким образом, вы, по крайней мере, увидите, что он вызывается…2. Отличный ответ, Джон. Спасибо. На самом деле я получал только одну строку. Объяснение о компиляторе было очень полезным.
Ответ №2:
Я считаю params string
, что должно быть сопоставлено, It.IsAny<string[]>()
а не It.IsAny<string>()
Ответ №3:
Используя Moq, приведенный ниже код работает для настройки обратного вызова метода с аргументом params. Определение второго аргумента как массива делает трюк.
MockLogger
.Setup(x => x.Info(It.IsAny<string>(), It.IsAny<object[]>()))
.Callback<string, object[]>((x, y) => _length = x.Length);