У меня есть класс, который использует шаблон стратегии, который я хотел бы протестировать. Он имеет зависимость от класса типа IResolver, который возвращает некоторый экземпляр класса типа ICalculator. Поэтому мне нужен объект Moq, который представляет распознаватель и при вызове возвращает другой объект Moq, представляющий калькулятор. У меня есть этот тест ниже:
public void UpperScoreManager_AddScoring_UpdatesScoreCorrectly()
{
var expectedScore = 10;
var mockCaluclator = new Mock < IScoreCategoryCalculator > ();
mockCaluclator.Setup(c => c.CalculateScore(It.IsAny < DiceSet > ()))
.Returns(expectedScore);
var mockResolver = new Mock < IScoreCategoryCalculatorResolver > ();
mockResolver.Setup(r => r.Resolve(It.IsAny < ScoreCategories > ()))
.Returns(mockCaluclator.Object);
var manager = new Managers.ScoreManager.UpperScoreManager.UpperScoreManager(mockResolver.Object);
manager.AddScoring(ScoreCategories.Aces, DiceSet.Create(new int[] { 1, 2, 3, 4, 5 }));
Assert.Equal(expectedScore, manager.Score);
}
А вот тестируемая функция
public void AddScoring(ScoreCategories category, DiceSet diceSet)
{
IScoreCategoryCalculator scoreCalculator = _scoreCalculatorResolver.Resolve(category);
Score += scoreCalculator.CalculateScore(diceSet);
}
Модульный тест не пройден из-за какой-то ошибки с настройкой Moq:
System.ArgumentException: объект типа 'Yahtzee.Core.Enums.ScoreCategories' не может быть преобразован в тип 'Yahtzee.Core.Interfaces.IScoreCategoryCalculator'
Я не понимаю эту ошибку ( Я не получаю это, пока я фактически не запускаю юнит-тест Когда я отлаживаю тест, первая строка моей тестируемой функции работает правильно
IScoreCategoryCalculator scoreCalculator = _scoreCalculatorResolver.Resolve(category);
Так что мой пробный распознаватель разрешает некоторые IScoreCategoryCalculator
. Следующая строка, однако, где происходит сбой. Если я сделаю QuickWatch
в этой строке в Visual Studio, я смогу увидеть это:
Есть идеи, что я здесь делаю неправильно? Может ли Moq вернуть другой объект Moq?
РЕДАКТИРОВАТЬ Пересматриваемые интерфейсы выглядят так:
public interface IScoreCategoryCalculator
{
ScoreCategories Type { get; }
int CalculateScore(DiceSet diceSet);
}
public interface IScoreCategoryCalculatorResolver
{
IScoreCategoryCalculator Resolve(ScoreCategories scoreCategory);
}
РЕДАКТИРОВАНИЕ 2 Отображение полного стека
Трассировка стека: RuntimeType.TryChangeType (значение объекта, подшивка подшивки, культура CultureInfo, логическое значение needsSpecialCast) RuntimeType.CheckValue (значение объекта, подшивка подшивки, культураInfo, BindingFlags invokeAttr) MethodBase.CheckArguments , Binder Binder, BindingFlags invokeAttr, CultureInfo culture, Signature sig) RuntimeMethodInfo.InvokeArgumentsCheck (Object obj, BindingFlags invokeAttr, Binder binder, Object [] параметры, CultureInfo culture) RuntimeMethodInfo.Invoke (Object obj, binding Binding) Bindinder invinding Binding Binding параметры, культура CultureInfo) Delegate.DynamicInvokeImpl (Object [] args) Delegate.DynamicInvoke (Object [] args) Extensions.InvokePreserveStack (Delegate del, Object [] args) ReturnLazyValueResponse.RespondTo (вызов с вызовом) метод вызывания (метод вызова) катион) FindAndExecuteMatchingSetup.Handle (вызов-вызов, фиктивная ложь) IInterceptor.Intercept (вызов-вызов) Interceptor.Intercept (вызов IInvocation) AbstractInvocation.Proceed () UpperScoreManagerTests.UpperScoreManager_AddScoring_UpdatesScoreCorrectly () строка 18