我希望为Service Fabric参与者编写一些单元测试。指南here建议使用名为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)自己重新创建该模拟库的功能,这样我就可以在创建具体对象之前模拟该方法
有没有办法不借助#2而接近#1?
答案 0 :(得分: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
移到带有接口的单独类中,使用依赖注入并为测试/实际运行传递不同的实现。