joh*_*son 3 c# unit-testing mocking fakeiteasy
我有一个界面
public interface IInterface { void DoSomething(); }
Run Code Online (Sandbox Code Playgroud)
另一个接口
public interface IOtherInterface : IInterface { }
Run Code Online (Sandbox Code Playgroud)
抽象类
public abstract class AbstractClass : IInterface
{
public void DoSomething()
{
Console.WriteLine("Got here");
}
}
Run Code Online (Sandbox Code Playgroud)
我正在编写一个单元测试和假 IotherInterface。抽象类已经包含我想要用于单元测试的有用方法。我将如何A.Fake<IOtherInterface>();继承AbstractClass?
这是我到目前为止所尝试过的,但它不起作用 - AbstractClass.DoSomething 没有被击中。
IOtherInterface fake = A.Fake<IOtherInterface>(builder => builder.Implements(typeof (AbstractClass)));
fake.DoSomething();
Run Code Online (Sandbox Code Playgroud)
当然,如果我制作一个像这样的代理:
var abstractFake = A.Fake<AbstractClass>();
A.CallTo(() => fake.DoSomething()).Invokes(abstractFake.DoSomething);
fake.DoSomething();
Run Code Online (Sandbox Code Playgroud)
...事情按我想要的方式进行。是否有内置机制可以实现此目的,以便我不需要该代理abstractFake对象?
更新
我需要IOtherInterface,因为我有一个客户端类需要 IotherInterface 作为依赖项:
class Consumer
{
public Consumer(IOtherInterface otherInterface)
{
otherInterface.DoSomething();
}
}
Run Code Online (Sandbox Code Playgroud)
var fake = (IOtherInterface) A.Fake<AbstractClass>(builder =>
builder.Implements(typeof(IOtherInterface)));
A.CallTo(() => fake.DoSomething()).CallsBaseMethod();
fake.DoSomething();
Run Code Online (Sandbox Code Playgroud)
Implements仅适用于接口,因此正确的使用方法是伪造接口或类并用于Implements添加其他接口。我认为它应该向你抱怨,所以当 IFakeOptionsBuilder.Implements 传递一个非接口时,我提出了抱怨,这在 FakeItEasy 2.0.0 中得到了修复。
这CallsBaseMethod将确保抽象类的方法被执行。
我会推荐builder.CallsBaseMethods(),但这无法重定向呼叫。我认为这是因为它正在重定向AbstractClass.DoSomething,但是当我们将假值投射到IOtherInterface并调用时DoSomething,它不匹配。我提出了调查Implements和CallsBaseMethods之间的相互作用。