AutoFake指定的对象不被识别为伪对象。尝试使用sut的方法时出现问题

时间:2018-06-01 05:49:38

标签: autofac fakeiteasy

我遇到了一个与模仿sut对象自己的方法有关的问题,如下所示。

AutoFake FakeResolver = new AutoFake();
ProductQueryService _sut = FakeResolver.Resolve<ProductQueryService>();
// stubing another virtual method in the testing object itself
A.CallTo(() => _sut.GetLookupCache()).Returns(Task.FromResult(fakeData)); // throws ArgumentException:The specified object is not recognized as a fake object

//method under test is GetBrands
List<BrandDto> brands = await _sut.GetBrands();

对此有任何建议吗?

1 个答案:

答案 0 :(得分:0)

我认为问题在于Autofac.Extras.FakeItEasy不会伪造具体类型,而是回到创建所请求类型的实际实例的默认容器行为。我不是Autofac专家,但这是我的理由:

the docs中,我们看到了

  

... package允许您使用Autofac容器在单元测试中为具体和假抽象实例自动创建虚拟依赖项

措辞有点含糊不清,但我认为它会说明将提供具体的依赖关系并抽象实例。

然后,我看了一下实现,found in FakeRegistrationHandler这个:

if (typedService == null ||
    (!typedService.ServiceType.GetTypeInfo().IsInterface && !typedService.ServiceType.GetTypeInfo().IsAbstract) ||
    (typedService.ServiceType.GetTypeInfo().IsGenericType && typedService.ServiceType.GetGenericTypeDefinition() == typeof(IEnumerable<>)) ||
    typedService.ServiceType.IsArray ||
    typeof(IStartable).IsAssignableFrom(typedService.ServiceType))

这是检查扩展程序是否伪造所请求的服务类型的检查。具体的ProductQueryService不是一个接口或抽象,所以我认为容器什么都不做。

我没有看到一种简单的方法来指示扩展程序伪造所有具体类型,但我确定你可以为任何具体类型(或一组类型 - 可能是一切)添加一次性注册在您的名称空间中)您喜欢。

我打算建议在Autofac上提出问题,但我看到you've done so。我希望我先看看那里。

我还要提醒一般,伪造被测系统不是我测试技术的首选。如果可能的话,我会提取一个可以注入你的SUT的依赖项。然后假装它。如果表示为接口或抽象类,您可以轻松使用Autofac.Extras.FakeItEasy来提供它。

与此同时,我将在Autofac.Extras.FakeItEasy issue 14处做一些笔记。