moq设置未返回预期值
本文关键字:返回 设置 moq | 更新日期: 2023-09-27 17:58:08
我正在使用Nunit和Autofac的Moq来设置测试
[TestFixture]
public class SomeTests
{
[OneTimeSetUp]
public void Initialize()
{
}
[Test]
public void SalaryCheck()
{
using (var mock = AutoMock.GetLoose())
{
// Arrange
mock.Mock<ICommonServices>().Setup(x => x.AddTwoNumbers(1,2)).Returns(5);
var sut = mock.Create<SomeManager>();
// Act
int actul = sut.CalculateSalary(1);
var expected = 5;
// Assert
Assert.AreEqual(expected, actul);
}
}
}
CalculateSsalary函数类似于以下
public int CalculateSalary(int hours)
{
var addres = _commonService.AddTwoNumbers(5,3);
if (addres == 5)
{
return addres * hours;
}
else
{
return 100;
}
}
我希望AddTwoNumbers函数是一个外部依赖项,无论如何都返回5。这就是我在嘲笑它之后设置它的原因。但当我调试这个测试时,它看起来像是进入了calsulate salary函数,但为AddTwoNumbers函数返回了一个"0"。这是一种默认值或空值。
它不会返回我5,即我设置它返回的内容。
您需要使用It.IsAny<int>()
即
mock.Mock<ICommonServices>().Setup(x => x.AddTwoNumbers(It.IsAny<int>(),It.IsAny<int>())).Returns(5);
当模拟返回抽象的方法时,请确保对It的调用中的类型为IsAny<YourType>()实际上与正在模拟的方法的参数类型相匹配。
给定一个以IEnumerable为参数的方法:
interface IQueueItemRepository {
IQueueItem GetFirstNotIn(IEnumerable<Guid> guids)
}
在下面的示例中,只有当使用Collection作为参数调用.GetFirstNotIn时,才会调用.Setup。
Mock<IQueueItemRepository> queueMock = new Mock<IQueueItemRepository>();
queueMock
.Setup(x => x.GetFirstNotIn(It.IsAny<Collection<Guid>>()))
.Returns(new QueueItem());
换句话说,如果您正在测试的代码从未使用Collection调用.GetFirstNotIn,则您的.Setup将永远不会被调用。它可能在整个代码中以IEnumerable为参数进行大量调用,但这些调用与.Setup.不匹配
因此,请确保将您的参数类型与相匹配。设置类型:
Mock<IQueueItemRepository> queueMock = new Mock<IQueueItemRepository>();
queueMock
.Setup(x => x.GetFirstNotIn(It.IsAny<IEnumerable<Guid>>()))
.Returns(new QueueItem());
除了其他答案所指出的之外,我想提到的是,您显然需要匹配所有的设置标准,才能运行Returns
。我设置了如下效果:
myRetriever.Setup(ar => ar.GetEvents(It.IsNotNull<HttpClient>(), It.Is<FilterCriteria>(s => validate(s)))).Returns(Task.FromResult(new List<MyClass>
{
new MyClass
{
// ...
}
})).Verifiable();
但是,validate(s)
返回了false
,因此Returns
从未运行过。不幸的是,这导致测试失败是由于Null指针异常(而不是由于Setup
中列出的条件不满足)。