.NET 中的 Mongodb 单元测试
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12804662/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Mongodb unit testing in .NET
提问by F0rc0sigan
I am trying to do tdd and use mongodb as database. But i cant resolve problem of mocking mongodb. Is there any ability to mock mongodb for unit testing in .NET?
我正在尝试执行 tdd 并使用 mongodb 作为数据库。但我无法解决模拟 mongodb 的问题。是否有能力模拟 mongodb 以在 .NET 中进行单元测试?
Update
更新
I found very good soltion reading blog. You can find it here:
我发现非常好的解决方案阅读博客。你可以在这里找到它:
回答by casperOne
Instead of mocking MongoDB, you should be mocking a layer on top ofMongoDB.
您应该模拟 MongoDB之上的一个层,而不是模拟MongoDB。
You might want to consider an interface that exposes the operations on your repository which are agnostic to the underlying data store. For example, you might want an interface that abstracts out operations on Studenttypes, like so:
您可能需要考虑一个接口,该接口公开存储库上的操作,这些操作与底层数据存储无关。例如,您可能需要一个抽象出Student类型操作的接口,如下所示:
public interface IStudentOperations
{
void Add(Student student);
}
When you create your other dependencies, you inject instances of the above interface, or whichever higher-level abstractions you choose.
当您创建其他依赖项时,您会注入上述接口的实例,或者您选择的任何更高级别的抽象。
The point is, don't expose MongoDB directly.
关键是,不要直接暴露 MongoDB 。
Once you do that, you can mock the interfaces you create all you want, having one implementation for testing against the mock implementation, and then an actual implementation with it's own tests to validate that operations on the implementation are correct when the underlying implementation is with MongoDB.
一旦你这样做了,你就可以模拟你创建的所有你想要的接口,有一个实现来测试模拟实现,然后一个实际的实现,它自己的测试来验证当底层实现时,实现上的操作是正确的MongoDB。
While it's definitely possible to mock most of MongoDB's classes (as the methods are virtual), you gain the benefit of being persistence agnostic; if you want to switch to say, CouchDB or elasticsearch, you don't have to change the calls to these interfaces, you simply create a new implementation.
虽然肯定可以模拟 MongoDB 的大多数类(就像方法一样virtual),但您可以获得与持久性无关的好处;如果您想切换到 CouchDB 或 elasticsearch,则不必更改对这些接口的调用,只需创建一个新实现即可。
Because you are trying to test the implementation of the repository, then you are generally fine, as has been stated before, most of MongoDB's functions are virtual, which is friendly to most mocking libraries.
因为您正在尝试测试存储库的实现,那么您通常没问题,如前所述,MongoDB 的大部分功能都是virtual,这对大多数模拟库都很友好。
That said, you'll have to make sure that you pass the MongoDatabaseintoyour repository (not create it inthe repository) so that in your unit tests, you can create the appropriate mock and then pass it into your repository implementation for testing.
也就是说,您必须确保将 传递MongoDatabase到您的存储库中(而不是在存储库中创建它),以便在您的单元测试中,您可以创建适当的模拟,然后将其传递到您的存储库实现中进行测试。
回答by David Hu
You need a repository/DAL layer to hide implementation details. Something like this:
您需要一个存储库/DAL 层来隐藏实现细节。像这样的东西:
public interface IDataContext<T>
{
// Query
IList<T> GetAll<T>();
IList<T> GetByCriteria<T>(Query query);
T GetByID<T>(string id);
// CUD
void Add(T item);
void Delete(T item);
void Save(T item);
}
- For production code, implement the interface with mongo db operations with the assistance of C# driver
- For unit test codes, mock the interface with an in-memory collection
- 对于生产代码,在 C# 驱动程序的帮助下实现与 mongo db 操作的接口
- 对于单元测试代码,使用内存中的集合模拟接口
It looks straightforward to mock Add/Delete/Save, and the intersting part is query function. Fortunately, since mongo C# driver supports LINQ expressions, we can use LINQ as the query language rather than reinventing the wheels.
模拟添加/删除/保存看起来很简单,有趣的部分是查询功能。幸运的是,由于 mongo C# 驱动程序支持 LINQ 表达式,我们可以使用 LINQ 作为查询语言而不是重新发明轮子。
For example, the production code may look like:
例如,生产代码可能如下所示:
// collection is a MongoCollection<T> object
var items = collection.AsQueryable().Where(...linq expression...);
And unit test code (if you go with Shim, MS test):
和单元测试代码(如果你使用 Shim,MS 测试):
using (ShimsContext.Create())
{
ShimLinqExtensionMethods.AsQueryableOf1MongoCollectionOfM0(
(MongoCollection<T> x) => Fake_DB_Collection.AsQueryable());
// After this, the above "collection.AsQueryable()" will be mocked as
// an in-memory collection, which can be any subclass of IEnumerable<T>
}
回答by cirrus
See this similar question: Mocking database in node.js?
看到这个类似的问题:在 node.js 中模拟数据库?
In short, mocking MongoDB isn't the right approach. Mocking your repository is adequate for testing your own units, but you'll still need to test against MongoDB if you want to make sure that you're using it correctly, or if you are relying on uniqueness constraints etc.
简而言之,嘲笑 MongoDB 不是正确的方法。模拟您的存储库足以测试您自己的单元,但是如果您想确保正确使用它,或者您依赖于唯一性约束等,您仍然需要针对 MongoDB 进行测试。

