5

我有兴趣使用“新 API”(从 ServiceStack.ServiceInterface.Service 继承)为使用 ServiceStack 创建的一些服务类编写单元测试(使用 NUnit)。在使用 AppHost 托管在 ASP.NET 应用程序中时,服务的 Db 属性已正确自动连接,但在该环境之外运行时,我似乎无法找出正确的技术。我在 ServiceStack 中看到了各种与测试相关的命名空间和类,但找不到一个明确的示例,其中服务的 Db 属性被注入,而不是简单地直接设置连接工厂,然后调用各种 IDbConnection 扩展方法(插入、选择等)。

我尝试让我的测试类从 ServiceStack.ServiceInterface.Testing.TestBase 继承并覆盖其 Configure 方法来注册一个 IDbConnectionFactory(使用“:memory:”),以及OrmLiteConfig.DialectProvider = SqliteDialect.Provider;在我的 TestFixtureSetUp 中进行设置,但是当我继续得到 NullReferenceException 时调用我的服务方法(在 ServiceStack.ServiceInterface.Service.get_Db() 处)。Funq 容器似乎没有自动连接任何东西。

SQLite 本身已正确设置,我可以通过绕过我的服务类并简单地执行直接 IDbConnection 调用的更简单的单元测试来确认这一点。

我错过了什么?

编辑

似乎对 ServiceStack 服务进行单元测试需要存在主机和客户端,尽管看起来有一些方法可以设置它以避免序列化成本(使用 DirectServiceClient,如此处所示 ——尽管我没有成功地让它在我的情况下工作。我设法使用 AppHostHttpListenerBase 方法(请参见此处)使其工作,尽管它更多的是集成测试而不是单元测试(因此速度较慢)。

4

1 回答 1

5

测试文档展示了几种不同的注入依赖项的方法。

如果您查看基本服务的实现,它只会从以下位置创建DbIDbConnectionFactory

private IDbConnection db;
public virtual IDbConnection Db
{
    get { return db ?? (db = TryResolve<IDbConnectionFactory>().OpenDbConnection()); }
}

它只是从本地或全球IResolverIOC 容器中解析:

public static IResolver GlobalResolver { get; set; }

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

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

因此,要注入您自己的依赖项(使用 Service 基类时),您只需要IAppHost使用您的服务所需的依赖项配置一个,您可以使用它:

using (var appHost = new BasicAppHost {
    ConfigureContainer = c => {
        c.Register<IDbConnectionFactory>(new ...);
    }
}.Init())
{
  //...    
}

然后您可以在您的服务上设置它以及您的服务需要的任何您自己的依赖项,例如:

var service = appHost.ResolveService<MyService>();

这将自动装配在您的 AppHost 中配置的所有依赖项,您还可以通过正常的属性访问添加自己的特定于测试的依赖项,例如:

var service.MyDependency = new Mock<IMyDependency>().Object;

从那时起,您可以照常调用和测试您的 C# 类方法:

var response = service.Get(new RequestDto { ... });
Assert.That(response.Result, Is.Equal("Expected Result from DB"));
于 2013-01-10T18:54:49.503 回答