使用xUnit与Moq基于其他方法返回值验证方法执行情况
使用xUnit + Moq 验证方法执行与依赖返回值的关联测试
咱们来一步步拆解这个测试需求哈,核心就是要根据依赖对象A的M1方法不同的返回结果,验证M2方法的执行次数是否符合预期。下面直接上具体的测试代码和对应的场景解释:
测试场景1:M1首次调用就返回true,M2完全不执行
当M1第一次调用就返回true时,Mb方法里的循环会直接触发return,M2根本没机会执行。对应的测试代码如下:
[Fact] public void Mb_WhenM1ReturnsTrueFirstTime_DoesNotCallM2() { // Arrange var mockA = new Mock<A>(); // 设置M1第一次调用返回true mockA.Setup(a => a.M1()).Returns(true); var bInstance = new B(mockA.Object); // Act bInstance.Mb(); // Assert // 验证M2从未被调用过 mockA.Verify(a => a.M2(), Times.Never); }
测试场景2:M1前N次返回false,第N+1次返回true,验证M2被调用N次
比如我们模拟M1前3次返回false,第4次返回true,那么Mb里的循环会执行3次M2,第4次触发return。用SetupSequence可以轻松控制M1的返回序列:
[Fact] public void Mb_WhenM1ReturnsFalseThreeTimesThenTrue_CallsM2ThreeTimes() { // Arrange var mockA = new Mock<A>(); // 设置M1的返回序列:前3次false,第4次true mockA.SetupSequence(a => a.M1()) .Returns(false) .Returns(false) .Returns(false) .Returns(true); var bInstance = new B(mockA.Object); // Act bInstance.Mb(); // Assert // 验证M2被精确调用3次 mockA.Verify(a => a.M2(), Times.Exactly(3)); }
测试场景3:M1始终返回false,验证M2被调用6次
因为Mb里的循环是i从0到5,总共6次迭代。如果M1每次都返回false,那么每次循环都会执行M2,总共调用6次:
[Fact] public void Mb_WhenM1AlwaysReturnsFalse_CallsM2SixTimes() { // Arrange var mockA = new Mock<A>(); mockA.Setup(a => a.M1()).Returns(false); var bInstance = new B(mockA.Object); // Act bInstance.Mb(); // Assert mockA.Verify(a => a.M2(), Times.Exactly(6)); }
关键知识点总结
- 用
Mock<A>创建依赖的模拟实例,完全掌控M1的返回值,避免真实逻辑的干扰 SetupSequence是Moq里控制方法多次调用返回不同结果的利器,特别适合循环中的条件判断场景Verify方法搭配Times枚举(比如Never、Exactly(n)),是验证目标方法是否按预期执行的核心手段
内容的提问来源于stack exchange,提问作者Guille
相关产品推荐
相关产品推荐

