【问题标题】:Injecting a fake concrete class via FakeItEasy and AutoFixture通过 FakeItEasy 和 AutoFixture 注入一个假的具体类
【发布时间】:2020-03-29 08:45:19
【问题描述】:

我有一个类,我想测试一个具体类 (MyClient) 的注入位置。

private readonly MyClient _client;

public Sync(MyClient client)
{
    _client = client;
}

我们使用 xUnit、AutoFixture 和 FakeItEasy 进行测试。在向类注入接口时,这一切都很好。

但是,当使用以下测试设置时

[Theory]
[AutoFakeData]
public async Task It_should_invoke_client(
    [Frozen]MyClient geoClient,
    [Frozen]ILogger logger,
    Sync sync)
{
    // Act
    await sync.Run(null, logger);

    //Assert
    A.CallTo(() => myClient.SyncAllAsync(A<CancellationToken>.Ignored)).MustHaveHappenedOnceExactly();
}

伪造的GeoClient 不会注入sync 参数。创建的sync 表明注入的MyClient 不是Faked 对象。

System.ArgumentException : Some.Namespace.MyClient 类型的对象“Some.Namespace.MyClient”未被识别为假对象。

通过sync 调试时,我发现这是正确的。一个“正常”MyClient 已被注入到被测系统中。

根据我从文档中了解到的情况,这应该可以工作。我可能遗漏了一些明显的步骤,但找不到。

【问题讨论】:

    标签: c# xunit autofixture fakeiteasy


    【解决方案1】:

    AutoFakeItEasy 仅在请求的样本属于抽象类型或接口类型时才提供假货。见FakeItEasyRelay

    return type.GetTypeInfo().IsAbstract || type.GetTypeInfo().IsInterface;
    

    您似乎可以通过提供自定义 ISpecimenBuilder 中继来覆盖它,但我没有尝试过。

    【讨论】:

    • 谢谢,创建我自己的ISpecimenBuilder 作品。我已经通过fixture.Customizations.Add(new ConcreteTypeSpecimenBuilder()) 添加了它,IsFakeableSpecification 有一行 return type.GetTypeInfo().IsClass; 而不是原来的。我会检查我是否可以稍微重构一下这段代码,让它变得更好。
    • 我想出的最干净的解决方案是创建一个FakeItEasyRelay 的派生类,它使用基本构造函数来“注入”我自己的IRequestSpecification,然后它会执行@987654330 @(+ 原始支票)。这是通过fixture.Customizations.Add(new RelayForConcreteTypes()); 添加的
    猜你喜欢
    • 2011-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-30
    • 1970-01-01
    相关资源
    最近更新 更多