C# NET中的Mongodb单元测试
我正在尝试使用tdd和mongodb作为数据库。但我无法解决嘲笑mongodb的问题。有没有能力在.NET中模拟mongodb进行单元测试C# NET中的Mongodb单元测试,c#,.net,unit-testing,mongodb,mocking,C#,.net,Unit Testing,Mongodb,Mocking,我正在尝试使用tdd和mongodb作为数据库。但我无法解决嘲笑mongodb的问题。有没有能力在.NET中模拟mongodb进行单元测试 更新 我发现读博客很好的解决方案。 您可以找到它:您不应该模拟MongoDB,而应该模拟MongoDB之上的一个层 您可能需要考虑一个接口,该接口公开了对基础数据存储区不可知的存储库上的操作。例如,您可能需要一个接口来抽象出Student类型上的操作,如下所示: public interface IStudentOperations { void
更新 我发现读博客很好的解决方案。
您可以找到它:您不应该模拟MongoDB,而应该模拟MongoDB之上的一个层
您可能需要考虑一个接口,该接口公开了对基础数据存储区不可知的存储库上的操作。例如,您可能需要一个接口来抽象出
Student
类型上的操作,如下所示:
public interface IStudentOperations
{
void Add(Student student);
}
当您创建其他依赖项时,您将注入上述接口的实例,或者您选择的更高级别的抽象
关键是,不要直接公开MongoDB
一旦您这样做了,您就可以对您创建的所有接口进行模拟,让一个实现针对模拟实现进行测试,然后是一个实际的实现,该实现具有自己的测试,以验证当底层实现使用MongoDB时,实现上的操作是否正确
虽然这是肯定的,但你获得了持久性不可知论的好处;如果您想切换到CouchDB或elasticsearch,则不必更改对这些接口的调用,只需创建一个新的实现
因为,正如前面所述,您一般都很好,MongoDB的大多数函数都是
虚拟的
,这对大多数模拟库都很友好
也就是说,您必须确保将
MongoDatabase
传递到您的存储库中(而不是在存储库中创建),以便在单元测试中,您可以创建适当的模拟,然后将其传递到存储库实现中进行测试。请参见类似问题:
简言之,嘲笑MongoDB不是正确的方法。模拟您的存储库足以测试您自己的单元,但是如果您想确保正确使用MongoDB,或者如果您依赖于唯一性约束等,您仍然需要对MongoDB进行测试。您需要一个存储库/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);
}
公共接口IDataContext
{
//质疑
IList GetAll();
IList GetByCriteria(查询);
T GetByID(字符串id);
//反刍
无效添加(T项);
作废删除(T项);
作废保存(T项);
}
- 对于生产代码,在C#driver的帮助下实现与mongo db操作的接口
- 对于单元测试代码,使用内存集合模拟接口
// collection is a MongoCollection<T> object
var items = collection.AsQueryable().Where(...linq expression...);
//集合是MongoCollection对象
var items=collection.AsQueryable(),其中(…linq表达式…);
和单元测试代码(如果使用Shim,MS测试):
使用(ShimsContext.Create())
{
ShimlinkExtensionMethods.asQueryOfMongoCollectionOf0(
(MongoCollection x)=>Fake_DB_Collection.AsQueryable());
//在此之后,上面的“collection.AsQueryable()”将被模拟为
//内存中的集合,可以是IEnumerable的任何子类
}
虽然我同意casperOne的观点,但是可以用大多数模拟框架模拟MongoDB驱动程序的类,因为公共方法是虚拟的。我将使用存储库模式。所以我需要嘲笑所有人,拯救,和其他人。这就是为什么我需要嘲笑mongo@kfuglsang更新了答案,具有不直接模拟MongoDB的优点。@F0rc0sigan您是在测试存储库的实现,还是在调用存储库?@F0rc0sigan抱歉,堆栈溢出不是代码编写服务。您还没有指出要模拟的方法、尝试过的方法或正在使用的模拟库。没有足够的信息,甚至无法开始尝试提供示例。GetByCriteria应返回IQueryable或IEnumerable
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>
}