【问题标题】:Assert that a call was not made with any generic parameters using FakeItEasy断言没有使用 FakeItEasy 使用任何通用参数进行调用
【发布时间】:2017-06-19 12:25:18
【问题描述】:

免责声明 - 这与How to use FakeItEasy to assert a method was not called 不是同一个问题

说明

我有一段代码可以向 IOC 容器注册内容,我可以在测试中使用 FakeItEasy 来确保进行注册。

我正在努力研究如何确保不会拨打意外电话。

快速回购(问题归结为几个测试类 - 这不是真正的实现)

public class Foo
{
    private readonly ICustomContainer m_CustomContainer;

    public Foo(ICustomContainer customContainer)
    {
        m_CustomContainer = customContainer;
    }

    public void Bar()
    {
        m_CustomContainer.Register<IMyInterface, IMyImplementation>();
    }
}

public interface ICustomContainer
{
    void Register<TInterface, TImplementation>() where TImplementation : TInterface;
}

public class UnitTest1
{
    [Fact]
    public void Test1()
    {
        //Arrange
        ICustomContainer fake = A.Fake<ICustomContainer>();
        Foo objectUnderTest = new Foo(fake);

        //Act
        objectUnderTest.Bar();

        //Assert
        A.CallTo(() => fake.Register<IMyInterface, IMyImplementation>()).MustHaveHappened();
        //A.CallTo(() => fake.Register<???>()).MustNotHaveHappened();  //Any generic parameter apart from <IMyInterface, IMyImplementation> must not have happened
    }
}

上述测试将通过 - 这是正确的。如果将来我要在 Bar() 中添加另一个注册,它仍然会通过 - 这不是很好,因为我的测试只是测试已知场景。

我想要达到的目标

因此,鉴于上面为我的 IOC 容器 ICustomContainer 定义的接口,我想确保它仅按预期调用。

我已经调查过的内容

在过去使用过其他模拟框架(例如 TypeMock Isolator)后,我可以将假对象设置为抛出异常,除非进行特定(预期)调用。我不知道我是否可以用 FakeItEasy 做到这一点。另外TypeMock Isolator不支持.NET Core,所以对我没有好处。

如果我有一个不使用泛型参数的方法,我可以让 FakeItEasy 计算该方法被调用的次数,并期望除了测试预期之外,它还被任何参数调用来电。这当然是一个选项,但这意味着我必须在我的接口上创建一个外观(我猜是作为扩展方法或包装器)来接收类型参数而不是泛型参数,这意味着我失去了预编译时间使用泛型参数约束时收到的警告。

实际问题

如何修改我的测试,以便我可以断言 未使用任何通用参数进行意外调用,而不是使用 .NET Core / FakeItEasy / xUnit 所期望的参数?

【问题讨论】:

    标签: c# unit-testing .net-core xunit.net fakeiteasy


    【解决方案1】:

    我可能过于简单化了,但听起来Strict Fake 可以帮助您。 做一个,然后明确地允许你想要的任何调用。

    //Arrange
    ICustomContainer fake = A.Fake<ICustomContainer>(x => x.Strict());
    
    // allow just the registrations you want to
    A.CallTo(() => fake.Register<IMyInterface, IMyImplementation>()).DoesNothing();
    
    Foo objectUnderTest = new Foo(fake);
    
    //Act
    objectUnderTest.Bar();
    
    //Assert
    A.CallTo(() => fake.Register<IMyInterface, IMyImplementation>()).MustHaveHappened();
    

    【讨论】:

    • 不,你并没有过于简单化;我不知道您可以做到这一点,并且刚刚尝试过,它似乎正是我想要的。很好的答案!
    • 很高兴能为您提供帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-15
    相关资源
    最近更新 更多