11

アプリと 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;
    }

ここで: Settings は Collection です 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)).Returns(collection.Object);

エラーは MongoCollection オブジェクトを参照しています。コンストラクターがあるとは思いませんでした。

テストを実行するにはどうすればよいですか?

4

2 に答える 2

7

この質問はおそらく次のものに関連しています: 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 の内部動作が変更された場合には役に立たないかもしれません。

于 2013-03-20T20:12:52.697 に答える
5

私は 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
}
于 2012-11-06T18:48:14.867 に答える