假设我有一个Service
对有依赖关系的TimeProvider
。
FakeTimeProvider
我现在要使用 AutoFixture 和 Moq来设置我的测试的使用情况:
public class FakeTimeProviderCustomization : ICustomization {
public void Customize(IFixture fixture) {
fixture.Customize<TimeProvider>
(c => c.FromFactory(() => new FakeTimeProvider()));
}
}
public class MoqAutoDataAttribute : AutoDataAttribute {
public MoqAutoDataAttribute()
: base(() => new Fixture()
.Customize(new AutoMoqCustomization())
.Customize(new FakeTimeProviderCustomization())
) {
}
}
[Theory, MoqAutoData]
public async Task Test_TimeRelatedStuff(
[Frozen] TimeProvider timeProvider,
Service sut) {
...
var fakeTimeProvider = timeProvider as FakeTimeProvider;
...
我可以避免FakeTimeProvider
每次都必须进行的转换吗?
您可以使用属性
Matching
提供的 API[Frozen]
,如下所示,但这需要您停用FakeTimeProviderCustomization
。本次测试通过:
为了演示目的,我
Service
这样定义:正如已经强调的那样,该
Matching.DirectBaseType
标准与 API 配合得不好Customize
,因为后者会覆盖前者。为了使上述测试通过,我停用了FakeTimeProviderCustomization
:显然,这会导致类无效,所以你最好删除它。我在这里展示上述内容只是为了明确解释如何使测试通过。
或者,如果您不想停用
FakeTimeProviderCustomization
,则可以使用另一个匹配规则。如果您的Service
构造函数如下所示Service(TimeProvider timeProvider)
,您也可以像这样编写测试:请注意,测试参数名称
timeProvider
与 的依赖项名称相同Service
。即使您FakeTimeProviderCustomization
因其他原因保持活动状态,这也有效。显然,正如这些附文所暗示的,这两种“解决方案”都很脆弱,因此最好的行动方案可能是重新考虑整体 API 设计和测试策略。