在使用NUnit对ServiceStack.OrmLite进行单元测试时,如何将Db注入Service类?

Nic*_*nes 5 nunit inversion-of-control ormlite-servicestack

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

我已经尝试让我的测试类继承自ServiceStack.ServiceInterface.Testing.TestBase并重写其Configure方法以注册IDbConnectionFactory(使用":memory:"),以及OrmLiteConfig.DialectProvider = SqliteDialect.Provider;在我的TestFixtureSetUp中设置,但是当我继续获得NullReferenceException时调用我的服务方法(在ServiceStack.ServiceInterface.Service.get_Db()处).似乎Funq容器没有自动连接任何东西.

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

我错过了什么?

编辑

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

myt*_*thz 5

关于测试文档显示了几种注入依赖关系的不同方法.

如果您查看基本服务的实现,它只需从以下内容创建DbIDbConnectionFactory:

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

它只是从本地或全局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>();
}
Run Code Online (Sandbox Code Playgroud)

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

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

然后,您可以根据自己的服务需要设置自己的服务,例如:

var service = appHost.ResolveService<MyService>();
Run Code Online (Sandbox Code Playgroud)

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

var service.MyDependency = new Mock<IMyDependency>().Object;
Run Code Online (Sandbox Code Playgroud)

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

var response = service.Get(new RequestDto { ... });
Assert.That(response.Result, Is.Equal("Expected Result from DB"));
Run Code Online (Sandbox Code Playgroud)