免责声明 - 这与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()
中添加另一个注册,它仍然会通过 - 这不是很好,因为我的测试仅测试已知的场景。
我想要实现的目标
因此,鉴于上面定义的ICustomContainer
接口是我的IOC容器,我想确保只按预期调用它。
我已经调查过的内容
过去使用过其他模拟框架,比如TypeMock Isolator,我可以将假对象设置为抛出异常,除非进行特定(预期)调用。我不知道我是否可以用FakeItEasy做到这一点。此外,TypeMock Isolator不支持.NET Core,因此对我没用。
如果我有一个不使用泛型参数的方法,我可以让FakeItEasy计算该方法被调用的次数,并期望除了测试预期之外还使用任何参数调用它调用。这当然是一个选项,但意味着我必须在我的界面上创建一个外观(作为扩展方法或包装器,我猜)接受类型参数而不是泛型参数,这意味着我失去了预编译时间警告我使用泛型参数约束。
实际问题
如何修改我的测试,以便我能断言一个意外的调用是没有除了我期望使用.NET Core / FakeItEasy / xUnit之外的任何通用参数?