XUnit集成AutoFixture时DI依赖Mock失效如何解决
问题根因
测试不通过是两个问题叠加导致的:
- 方法名笔误:手动编写的可运行基线测试调用的SUT方法是
LoginGo,两个基于AutoFixture的测试错误写成了Login,执行路径完全不对,根本没触发重定向逻辑,不可能验证到目标方法调用。 - Mock实例未绑定到SUT依赖:默认配置的
AutoMoqCustomization不会自动把你冻结的Mock<IServiceSomething2>和SUT构造函数需要的IServiceSomething2实例关联,创建SUT时框架会生成新的Mock对象注入,你配置Setup、执行Verify的都是自己手里的独立Mock实例,SUT压根没用到。
修复方案
方案1:手动初始化Fixture写法
只需要两步修改:
- 初始化
AutoMoqCustomization时开启ConfigureMembers = true,框架会自动将冻结的Mock实例和对应接口类型绑定,不需要手动调用Inject/Register,同时还会自动为Mock成员生成测试值,简化配置。 - 将测试中调用的方法名从
Login改回正确的LoginGo。
修正后的完整代码:
[Fact] public void testLogin() { var fixture = new Fixture().Customize(new AutoMoqCustomization() { ConfigureMembers = true }); var response = fixture.Freeze<Mock<IServiceSomething2>>(); response.Setup(r => r.RedirectToLoginPageWithInvalidLogin()); var sut = fixture.Create<Authenticate>(); sut.LoginGo("", "fake"); response.Verify(a => a.RedirectToLoginPageWithInvalidLogin(), Times.Once()); }
方案2:AutoData特性注入写法
同样两步修改:
- 在自定义
AutoMoqDataAttribute中初始化AutoMoqCustomization时,同样开启ConfigureMembers = true。 - 测试方法内将调用的方法名改回
LoginGo。
修正后的完整代码:
public class AutoMoqDataAttribute : AutoDataAttribute { public AutoMoqDataAttribute() : base(() => new Fixture().Customize(new AutoMoqCustomization { ConfigureMembers = true })) { } } [Theory, AutoMoqData] public void testLogin([Frozen]Mock<IServiceSomething2> response, Authenticate sut) { response.Setup(r => r.RedirectToLoginPageWithInvalidLogin()); sut.LoginGo("", "fake"); response.Verify(a => a.RedirectToLoginPageWithInvalidLogin(), Times.Once()); }
如果你使用的是4.17之前的老版本AutoFixture.AutoMoq,没有
ConfigureMembers配置项,可以在冻结Mock时显式指定匹配实现的接口:手动写法中Freeze传参asImplementedServices: true,特性写法中给[Frozen]加参数Matching.ImplementedInterfaces,效果完全一致。
内容的提问来源于stack exchange,提问作者Reiko0q
相关产品推荐
相关产品推荐

