我遇到了一个与模仿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();
对此有任何建议吗?
答案 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处做一些笔记。