我正在使用 DI 容器来创建用于集成测试的伪造品。我为应用程序工厂中的
ConfigureServices
函数中需要伪造的所有接口调用此方法:
public static IServiceCollection FakeWithBaseImplementation<T>(this IServiceCollection services)
where T : class
{
// Create a fake for the wrapper class
var sp = services.BuildServiceProvider();
var classImplementation = sp.GetService<T>();
var fake = A.Fake<T>(o => o.Wrapping(classImplementation!));
services.Remove<T>();
services.AddTransient(_ => fake);
return services;
}
每次测试后,我都会调用此方法来重置假货的状态:
public void ResetFakeServiceState<TServiceType>()
where TServiceType : notnull
{
var service = this.Services.GetRequiredService<TServiceType>();
if (Fake.IsFake(service))
{
Fake.ClearRecordedCalls(service);
}
}
但是,我看到在包装实现时,它不会创建 Fake,而是创建伪真实实例,而且我似乎无法 ClearRecordedCalls。行为是,如果我重写服务的方法,然后我
ClearRecordedCalls
然后执行另一个测试,该方法仍然会被重写。
我使用包装的原因是我仍然想使用原始实现和类构造函数的 DI 容器。我尝试使用带有
CallsBaseMethods()
选项的 Fake,它适用于调用基本方法,但它在构造函数内使用 Fakes 解析 DI,并且我想要真正的类来真正调用 DB 及其内部的内容。
我发现这一切的原因是,如果我单独执行测试,它们都会通过。但同时执行它们时,有些会失败。
但是,我看到在包装实现时,它不会创建 Fake 而是创建伪真实实例
我不明白这个。您能解释一下什么是伪真实实例以及它与假实例有何不同?我看到
T
是一个类,所以你的 Fake 将是一个派生自 T 的类。 Fake.IsFake
返回 false
吗?
而且我似乎无法清除RecordedCalls。行为是如果我 覆盖服务的方法,然后我 ClearRecordedCalls 然后我 执行另一个测试,该方法仍然会被覆盖。
ClearRecordedCalls
不应该恢复任何被覆盖的行为。也许您正在寻找 Fake.ClearConfiguration
(在即将发布的版本中将被 Fake.Reset
取代)。