2012-11-06 15 views
7

私は自分のアプリケーションとmongoデータベースの間にサービスレイヤーを持っています。MongoDBサービス層をテストするためにmoqを使用するにはどうすればよいですか?

私は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; 
    } 

[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); 
    } 

I: 設定コレクション あるMongoDatabaseは、私は私のテストとしてこれを試してみたMongoDBDriver.MongoDatabase

です「パラメータのないコンストラクタを見つけることができませんでした」というエラーが発生しました:

mongoDatabase.Setup(f => f.GetCollection(MongoCollections.Settings))。戻り値(collection.Object);

エラーは、MongoCollectionオブジェクトを参照しています。私はそれがコンストラクタを持っていたとは思わなかった。

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

+0

ドントモック、 'var collection = new Mock >();'と試してみてください –

+1

申し訳ありませんが、私はあなたが示唆していることを理解していません。 – Richard210363

答えて

3

私は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); 
    } 
} 

今、あなたのコードでは、あなたは(あなたが好きなDI方式を使用して)IMongoDBRepositoryを注入し、あなたのコードは次のようなものに見えるでしょう:

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 
} 
+0

これは私にいくつか考慮すべきものを与えてくれましたが、そのままは動作しません。メソッドにIMongoDBRepositoryオブジェクトを挿入することはできません。コードは実行時に実際のデータベースを読み取る必要があるため、IMongoDBRepositoryではなくMongoDatabaseを使用する必要があります。 – Richard210363

+0

また、MongoDatabase.GetCollection (name); GetCollectionは静的メソッドではないため、実行できません。私は基本的なアイデアを使用し、それを機能させることができるかどうかを見ていきます。 – Richard210363

7

この質問はおそらくに関連している:彼女の、とにかくHow do I mock MongoDB objects to test my data models?

私はリンクの質問で述べたように、eは、とにかく

 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変更の内部動作のいずれか。

+0

'collection'のコードはどこですか? – zsong

+2

不足していると思われる 'var collection = new Mock >(database.Object、" COLLECTIONNAME "、collectionSettings);およびいくつかの適切なcollectionSettings。 –

+0

MongoDBドライバーの変更の内部作業の意味を詳しく教えてください。新しいバージョンのC#MongoDB Driverにアップグレードするときに、API C#MongoDB Driverの変更を意味しますか? –

関連する問題