Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/264.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# NoSQL-如何为单元测试模拟数据库?_C#_.net_Nosql - Fatal编程技术网

C# NoSQL-如何为单元测试模拟数据库?

C# NoSQL-如何为单元测试模拟数据库?,c#,.net,nosql,C#,.net,Nosql,我正在研究NoSQL数据库,有一个关于单元测试的问题。对业务逻辑进行单元测试的合适方法是什么?如何模拟NoSQL数据库?您的业务逻辑不应该直接接触数据库,而是通过数据库访问层。这使您可以模拟中间层进行单元测试。为此,可以使用依赖项注入和模拟。有一些框架可以帮助您完成这两项工作,但您也可以手工完成。下面是一个例子: 假设我们有一个DAL: public class DBDataProvider: IDataProvider { public string getData() {

我正在研究NoSQL数据库,有一个关于单元测试的问题。对业务逻辑进行单元测试的合适方法是什么?如何模拟NoSQL数据库?

您的业务逻辑不应该直接接触数据库,而是通过数据库访问层。这使您可以模拟中间层进行单元测试。为此,可以使用依赖项注入和模拟。有一些框架可以帮助您完成这两项工作,但您也可以手工完成。下面是一个例子:

假设我们有一个DAL:

public class DBDataProvider: IDataProvider
{
    public string getData()
    {
         //SQL to get data from actual database.
    }
}
如您所见,这实现了一个接口,用于为您的业务层提供数据。它可能看起来像这样:

public Interface IDataProvider
{
     String getData();
}
public BusinessClass
{
    private IDataProvider dataProvider;

    public BusinessClass()
    {
        dataProvider = new DBDataProvider();
    }

    public BusinessClass(IDataProvider provider)
    {
        dataProvider = provider;
    }

    public void doBusinessStuff()
    {
        dataProvider.getData(); 
        //Do something with data.
    }

}
您的业务层可能如下所示:

public Interface IDataProvider
{
     String getData();
}
public BusinessClass
{
    private IDataProvider dataProvider;

    public BusinessClass()
    {
        dataProvider = new DBDataProvider();
    }

    public BusinessClass(IDataProvider provider)
    {
        dataProvider = provider;
    }

    public void doBusinessStuff()
    {
        dataProvider.getData(); 
        //Do something with data.
    }

}
因此,现在在您的生产代码中,您将使用默认构造函数创建业务类,该构造函数将自动创建与DB连接的类。但是,请注意,我们可以使用指定的IDataProvider创建BusinessClass。因此,您可以制作一个“假”数据提供程序用于测试:

public class MockDataProvider: IDataProvider
{
    public string getData()
    {
         //return some expected result that you can control, without doing a DB call.
    }
}
现在在测试中,您可以创建一个新的MockDataProvider,并将其传递到BusinessClass的构造函数中。您的业务类现在将使用模拟数据提供程序,而不是真正的数据库


在这里,我用手做了所有的事情,但它给了你一个如何工作的想法。在现实生活中,您可以使用模拟和依赖项注入框架为您编写一系列代码。

与模拟任何依赖项的方式相同。编写一个漂亮、整洁的契约,从中可以抽象出实现细节,然后模拟该契约。通常,这是通过使用数据访问层作为合同来实现的。
在不深入实际实现细节的情况下,假设您要测试的方法中有一个查询:(注意,我从一个ravenDB示例复制了这段代码,但我对ravenDB了解0,所以它甚至可能无法编译)

这将很难模拟/测试,因为它需要8080上本地主机上的db。现在,如果将此逻辑划分为另一个类:

public class AwesomeDAL
    public virtual void AddCompany(string name, string motto){
        using (var docStore = new DocumentStore("localhost", 8080).Initialize())
        using (var session = documentStore.OpenSession()){
            session.Store(new Company { Name = name, Motto = motto });;
            session.SaveChanges();
        }
}
并允许注入依赖项(AwesomeDal):


现在可以单独测试BL代码了。或者,您可以模拟数据库异常,或者需要测试的任何其他内容,因为您的数据访问层是抽象的,并且它的实现可以很容易地使用类似于或RhinoMocks的框架进行模拟。除了已经发布的(正确的)答案之外,让我提出一个替代解决方案:使用真正的开发数据库!没有什么比真实的东西更真实的了。如果您直接对其进行测试,至少您知道您的代码将实际运行


如果您可以轻松地提取数据库,我建议您这样做。

您是否有指向示例的链接?我试着搜索,但没找到多少。感谢您的回复。不要这样做,请使用RavenDB.Embedded并在内存中运行它-请参阅。另外,不要用RavenDB来使用DAL/BLL层,这没有什么意义。你也可以考虑内存中的DB来测试。问题是NoSQL技术。许多人有内存功能,其他人有自己的窍门。Graph DB不同于doc DB,就像两者都不同于RDBMS一样。Oleski,a)这被认为是一种非常糟糕的做法。b)这也是一种NoSQL解决方案,这里没有SQL。c) 这真的不管用哪一部分被认为是坏习惯,为什么不管用?