根据分支条件测试调用什么方法 - 除了控制器之外的所有测试都在接口后面

Testing what method is called based on branch conditions - everything tested except the controller is behind an interface

我是单元测试的新手,我有一个方法可以 return 是一个基于某些分支逻辑的 Func。我的问题是,单元测试看不到实际调用了什么方法,可能是因为它正在测试接口。我必须在设置中明确写下 returned 的方法,但是我认为这违背了测试的目的,因为我想测试分支中的 returned 是否正确逻辑。

这是接口中的方法定义:

Func<Task<IEnumerable<T>>> GetMethod(int param);

它 return 是这三个之一:

Task<IEnumerable<T>> MethodOne();
Task<IEnumerable<T>> MethodTwo();
Task<IEnumerable<T>> MethodThree();

这是我在测试中的设置方式,问题是即使我在应该 return MethodOne 时编写实际代码 return MethodTwo,测试仍然通过了。但是,如果我不这样设置,测试只会看到调用 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 不喜欢将具体的 classes 与 Verify 一起使用 - 所以我不能在测试中使用具体的 class 实现:

这是在控制器中调用它的地方:

result = await methodInterface.GetMethod(5).Invoke();

return Ok(result);

有什么方法可以使用接口正确测试吗?或者我绝对应该测试一个具体的class?如果具体的 class 是唯一的方法,我们如何检查是否调用了 class 方法?我不知道 AutoMoq 中的 Verify() 方法。

提前致谢!

您需要决定是为控制器编写单元测试,还是为由控制器和 "method getter" 组成的系统编写集成测试。

如果是前者,您对测试 IGetMethodInterface 背后的逻辑不感兴趣,您应该简单地测试控制器调用返回的任何模拟实现。

如果是后者,您应该设置一个真正的控制器来调用 IGetMethodInterface 的真正实现,而无需任何模拟。