在已经实例化的具体类上模拟虚拟方法



我希望为 Service Fabric 参与者编写一些单元测试。此处的指南建议使用名为 ServiceFabric.Mocks 的 NuGet 包,该包简化了各种 Service Fabric 实体的启动模拟。

到目前为止,所有这些都是有道理的。我可以使用以下内容为我的参与者启动一个具体的实现:

private MyActor CreateActor(ActorId id) 
{
Func<ActorService, ActorId, ActorBase> factory = (service, actorId) => new MyActor(service, id);
var svc = MockActorServiceFactory.CreateActorServiceForActor<MyActor>(factory);
var actor = svc.Activate(id);
return actor;
}

只要我坚持包文档中的示例并测试单个方法的结果,我就可以了。但是,我有一个方法可以在 actor 中调用另一个方法并使用其结果。它如下所示:

public class MyActor : Actor, IMyActor 
{
public async Task<string> DoThis()
{
var result = await DoThat();
//...
}
public virtual async Task<string> DoThat()
{
//...
}
}

我希望能够在我的Actor中模拟DoThat方法,以便我可以测试DoThis方法,但是鉴于ServiceFabric.Mocks的结果是一个具体对象,因此不清楚如何做到这一点。

我认为前进的仅有的两种方式是: 1( 确定某种方法来创建已实例化的类的模拟 2(自己重新创建这个模拟库的功能,这样我就可以在创建具体对象之前模拟出该方法

有没有办法在不诉诸#1的情况下接近#2?

您可以在单元测试附近创建一个继承自MyActor的新类,而不是使用模拟,并出于测试目的覆盖DoThat实现:

private class MyTestActor : MyActor
{
public string Result {get; set;} = "ok";
public override Task<string> DoThat() { return Task.FromResult(Result); }
}

您的测试代码如下所示:

private MyActor CreateActor(ActorId id) 
{
Func<ActorService, ActorId, ActorBase> factory = (service, actorId) => new MyTestActor(service, id);
var svc = MockActorServiceFactory.CreateActorServiceForActor<MyTestActor>(factory);
var actor = svc.Activate(id);
return actor;
}

或者,您可以将逻辑从DoThat移动到具有接口的单独类中,使用依赖注入并传递不同的实现以进行测试/实际运行。

最新更新