[英]How would I use moq to test a MongoDB service layer?
我的應用程序和mongo數據庫之間有一個服務層。
我正在嘗試使用moq構建一個單元測試我對moq很新,所以我從我認為是一個微不足道的測試開始。
要測試的代碼:
public List<BsonDocument> GetAllSettings()
{
var collection = MongoDatabase.GetCollection<BsonDocument>("Settings");
var query = from e in collection.AsQueryable()
select e;
var settings = query.ToList();
return settings;
}
其中:設置是集合MongoDatabase是MongoDBDriver.MongoDatabase
我試過這個作為我的測試:
[Test()]
public void GetAllSettingsTest()
{
//Arrange
BsonDocument doc01 = new BsonDocument();
BsonDocument doc02 = new BsonDocument();
var mongoDatabase = new Mock<MongoDatabase>();
var collection = new Mock<MongoCollection<BsonDocument>>();
mongoDatabase.Setup(f => f.GetCollection(MongoCollection.Settings)).Returns(collection.Object);
collection.Object.Insert(doc01);
collection.Object.Insert(doc02);
ILogger logger = new Logger();
DatabaseClient.DatabaseClient target = new DatabaseClient.DatabaseClient(logger);
target.MongoDatabase = mongoDatabase.Object;
MongoCursor<BsonDocument> cursor = collection.Object.FindAllAs<BsonDocument>();
List<BsonDocument> expected = cursor.ToList();
List<BsonDocument> actual;
//Act
actual = target.GetAllSettings();
//Assert
Assert.AreEqual(expected, actual);
}
我收到的錯誤是“無法找到無參數構造函數”:
mongoDatabase.Setup(f => f.GetCollection(MongoCollections.Settings))。返回(collection.Object);
該錯誤指的是MongoCollection對象。 我認為它沒有構造函數。
我該怎么做才能讓我的測試運行?
這個問題很可能與以下內容有關: 如何模擬MongoDB對象來測試我的數據模型?
無論如何,這里是模擬所需的最小Moq配置
var message = string.Empty;
var serverSettings = new MongoServerSettings()
{
GuidRepresentation = MongoDB.Bson.GuidRepresentation.Standard,
ReadEncoding = new UTF8Encoding(),
ReadPreference = new ReadPreference(),
WriteConcern = new WriteConcern(),
WriteEncoding = new UTF8Encoding()
};
var server = new Mock<MongoServer>(serverSettings);
server.Setup(s => s.Settings).Returns(serverSettings);
server.Setup(s => s.IsDatabaseNameValid(It.IsAny<string>(), out message)).Returns(true);
var databaseSettings = new MongoDatabaseSettings()
{
GuidRepresentation = MongoDB.Bson.GuidRepresentation.Standard,
ReadEncoding = new UTF8Encoding(),
ReadPreference = new ReadPreference(),
WriteConcern = new WriteConcern(),
WriteEncoding = new UTF8Encoding()
};
var database = new Mock<MongoDatabase>(server.Object, "test", databaseSettings);
database.Setup(db => db.Settings).Returns(databaseSettings);
database.Setup(db => db.IsCollectionNameValid(It.IsAny<string>(), out message)).Returns(true);
var mockedCollection = collection.Object;
無論如何,正如我在鏈接問題中提到的,當MongoDriver的任何內部工作發生變化時,這可能沒有用。
我不熟悉MongoDbDriver.MongoDatabase,但如果它像我認為的那樣工作,那么你不能直接模擬它。 您需要抽象MongoDB訪問代碼,並模擬它。 這將是一個實際的單元測試。 例如
public interface IMongoDBRepository
{
Collection<T> GetCollection<T>(string name) where T BsonDocument;
}
public class MongoDbRepository : IMongoDBRepository
{
public Collection<T> GetCollection<T>(string name)
where T : BsonDocument
{
return MongoDatabase.GetCollection<BsonDocument>(name);
}
}
現在,在你的代碼中,你注入一個IMongoDBRepository(使用你喜歡的任何DI方法),你的代碼看起來像這樣:
private IMongoDBRepository _mongoDBRepository; //this gets injected
public List<BsonDocument> GetAllSettings()
{
var collection = _mongoDBRepository.GetCollection<BsonDocument>("Settings");
var query = from e in collection.AsQueryable()
select e;
var settings = query.ToList();
return settings;
}
最后你的單元測試:
[Test()]
public void GetAllSettingsTest()
{
//Arrange
BsonDocument doc01 = new BsonDocument();
BsonDocument doc02 = new BsonDocument();
var mongoDatabase = new Mock<IMongoDBRepository>();
var collection = new Mock<MongoCollection<BsonDocument>>();
mongoDatabase.Setup(f => f.GetCollection(MongoCollection.Settings)).Returns(collection.Object);
collection.Object.Insert(doc01);
collection.Object.Insert(doc02);
//rest of test
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.