簡體   English   中英

我如何使用moq來測試MongoDB服務層?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM