2017-06-19 80 views
3

免责声明任何通用的参数进行 - 这是不是How to use FakeItEasy to assert a method was not called断言,一个电话没有使用FakeItEasy

说明了同样的问题

我有一段代码与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()中添加另一个注册,它仍然会通过 - 这不太好,因为我的测试只测试已知场景。

我想实现

因此,鉴于上述对ICustomContainer这是我的IOC容器中定义的接口,我想以确保预期它只是调用。

我已经调查

已经使用其他嘲讽框架在过去如TypeMock隔离器,我可以设置假目标,除非有具体(预期)呼叫是由抛出异常。我不知道我是否可以用FakeItEasy做到这一点。另外TypeMock Isolator不支持.NET Core,所以对我来说不好。

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

实际问题

怎样更改我的测试,这样我可以断言,一个意外的电话是没有取得有比我用的是.NET的核心/ FakeItEasy期待其他任何泛型参数/的xUnit?

回答

3

我可能是过于简单化了,但它听起来像一个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(); 
+0

不,你不是简单化;我不知道你能做到这一点,并刚刚尝试过,它似乎正是我所期待的。很好的答案! – Jay

+1

我很高兴得到了协助。 –