我对单元测试很陌生,我有一个方法,基于一些分支逻辑返回一个Func。我的问题是,单元测试无法看到实际调用的是什么方法,可能是因为它在测试接口。我必须在设置中明确写出将返回什么方法,然而我认为这对我来说违背了测试的目的,因为我想测试在分支逻辑中返回的方法是否正确。
这是接口中的方法定义。
Func<Task<IEnumerable<T>>> GetMethod(int param);
它将返回这三个方法中的一个。
Task<IEnumerable<T>> MethodOne();
Task<IEnumerable<T>> MethodTwo();
Task<IEnumerable<T>> MethodThree();
这是我在测试中的设置,问题是即使我让实际代码返回MethodTwo,而它应该返回MethodOne,测试仍然因此而通过。但是,如果我不这样设置,测试就只能看到GetMethod被调用:(
var service = fixture.Freeze<Mock<IGetMethodInterface>>();
service.Setup(i => i.GetMethod(It.IsAny<int>()))
.Returns(() => service.Object.MethodOne());
var sut = fixture.Create<MethodController>();
await sut.CallGetMethod();
service.Verify(i => i.GetMethod(It.IsAny<int>()), Times.Once());
service.Verify(i => i.MethodOne(), Times.Once());
可悲的是,AutoMoq不喜欢具体的类被用于Verify--所以我不能在测试中使用具体的类实现。
这里是它在控制器中被调用的地方。
result = await methodInterface.GetMethod(5).Invoke();
return Ok(result);
有什么办法可以用一个接口来正确测试吗?或者我一定要测试一个具体的类?如果具体类是唯一的方法,我们如何检查一个类的方法是否被调用?我不知道类似AutoMoq中的Verify()方法。
先谢谢你了!
你需要决定你是在为控制器写单元测试,还是在为控制器和 "方法获取器 "组成的系统写集成测试。
如果是前者,你对测试背后的逻辑不感兴趣。IGetMethodInterface
和你应该简单地测试无论返回的模拟实现是否被控制器调用。
如果是后者,你应该设置一个真实的控制器,调用一个真实的 IGetMethodInterface
没有任何嘲讽。