模拟由另一个ServiceStack服务调用的ServiceStack服务的方法

时间:2014-04-25 14:51:16

标签: servicestack

我们假设我们的服务会调用ServiceStack中的其他服务。

从阅读中,这就是人们如何称呼另一项服务:

public class CompanyService : Service
{
    public SetupCompanyResponse Any(SetupCompany request)
    {
        var employeeService = base.ResolveService<EmployeeService>();

        // Do something with employeeService
        var response = employeeService.Any(new SetupEmployees());

        return new SetupCompanyResponse { NumOfEmployeesCreated = response.Count };
    }
}

问题:如果我是单位测试公司服务,如何模拟EmployeeService?

我能想到的最简单方法是生成一个IEmployeeService接口,以便它可以轻松模拟。但是,我不确定base.ResolveService<T>是否能够正确地解析和自动连接ServiceStack服务,而不是给定其接口,如下所示:

var employeeService = base.ResolveService<IEmployeeService>();

特别是当我们以这种方式注册服务时(我假设是根据具体类配置对象解析,而不是像IEmployeeService这样的接口)

public HelloAppHost() : base("Hello Web Services", typeof(HelloService).Assembly) { }

更新

显然,我可以通过以下方式实现这一目标:

1)将服务接口注册到其实现

public static void SetupServices(Container container)
{
    container.RegisterAs<EmployeeService, IEmployeeService>();
}

2)使用相同的确切代码来解决,除了现在我传入接口。该服务已成功解决。

var employeeService = base.ResolveService<IEmployeeService>();

3)我现在需要做的就是覆盖解析器,服务依赖应该是完全可以模拟的。

问题:这也是一种有效的方法吗?为什么或为什么不呢?

1 个答案:

答案 0 :(得分:2)

ServiceStack的Service class解析了IResolver的所有依赖关系,定义如下:

public interface IResolver
{
    T TryResolve<T>();
}

这可以通过实现看到的多种方式注入到ServiceStack的Service类中:

public class Service : IService, IServiceBase, IDisposable
{
    public static IResolver GlobalResolver { get; set; }

    private IResolver resolver;
    public virtual IResolver GetResolver()
    {
        return resolver ?? GlobalResolver;
    }

    public virtual Service SetResolver(IResolver resolver)
    {
        this.resolver = resolver;
        return this;
    }

    public virtual T TryResolve<T>()
    {
        return this.GetResolver() == null
            ? default(T)
            : this.GetResolver().TryResolve<T>();
    }
    ...
}

您可以使用它来控制服务如何解决依赖关系。

单元测试服务的简单方法是使用Testing wiki上的BasicAppHost,即:

appHost = new BasicAppHost().Init();
var container = appHost.Container;

container.Register<IDbConnectionFactory>(
    new OrmLiteConnectionFactory(":memory:", SqliteDialect.Provider));

container.RegisterAutoWired<CompanyService>();
container.RegisterAutoWiredAs<StubEmployeeService, EmployeeService>();

其中StubEmployeeService是EmployeeService的存根实现,例如:

public class StubEmployeeService : EmployeeService 
{
    public SetupEmployeesResponse Any(SetupEmployees request)
    {
        return new SetupEmployeesResponse  { ... };
    }
}

如果您更喜欢使用自己的模拟库,也可以使用任何注册方法ServiceStack's IOC Supports注册服务。