2012-11-06 12 views
7

Mam warstwę usługi między moją aplikacją a bazą danych mongo.Jak używać funkcji moq do testowania warstwy usługi MongoDB?

Próbuję zbudować test jednostkowy za pomocą moq Jestem całkiem nowy do moq, więc zacząłem od tego, co uważałem za trywialny test.

kod do testu:

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

Gdzie: Ustawienia to zbiór MongoDatabase jest MongoDBDriver.MongoDatabase

Próbowałem tego jako mojego testu:

[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 "Otrzymuję błąd z" Nie można znaleźć konstruktora bez parametrów "pod adresem:

mongoDatabase.Setup (f => f.GetCollection (MongoCollections.Settings)). Returns (collection.Object);

Błąd odnosi się do obiektu MongoCollection. Nie myślałem, że ma konstruktora.

Co mogę zrobić, aby uruchomić test?

+0

Donot mock, 'var collection = new Mock >();' and try –

+1

Przykro mi, nie rozumiem co sugerujesz. – Richard210363

Odpowiedz

3

Nie jestem zaznajomiony z MongoDbDriver.MongoDatabase, ale jeśli działa tak, jak sądzę, to nie można z niego kpić bezpośrednio. Musisz wyodrębnić kod dostępu MongoDB i wyśmiewać to. To byłby prawdziwy test jednostkowy. na przykład

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

Teraz, w kodzie, wstrzyknąć się IMongoDBRepository (przy użyciu dowolnej metody lubisz DI) i Twój kod będzie wyglądać tak:

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

i wreszcie test Jednostka:

[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

Dało mi to kilka rzeczy do rozważenia, ale nie zadziała tak jak jest. Nie można wstrzyknąć obiektu IMongoDBRepository do metody. Kod musi używać MongoDatabase, a nie IMongoDBRepository, ponieważ musi odczytywać prawdziwą bazę danych podczas działania. – Richard210363

+0

Ponadto MongoDatabase.GetCollection (nazwa); nie można tego zrobić, ponieważ GetCollection nie jest metodą statyczną. Wykorzystam podstawowy pomysł i zobaczę, czy mogę go uruchomić. – Richard210363

7

kwestia ta jest najprawdopodobniej związane z: How do I mock MongoDB objects to test my data models?

W każdym razie, jej e jest minimalna wymagana konfiguracja Moq mock

 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; 

Zresztą, jak już wspomniano w połączonych mowa, to nie może być przydatne, gdy którykolwiek z wewnętrznymi-wyrobisk zmian MongoDriver.

+0

Gdzie jest kod dla 'kolekcji'? – zsong

+2

Wygląda na to, że brakuje ... 'var collection = new Mock > (database.Object," COLLECTIONNAME ", collectionSettings);' i kilka odpowiednich ustawień kolekcji. –

+0

Czy mógłbyś rozwinąć to, co masz na myśli przez wewnętrzną pracę zmiany sterownika MongoDB? Czy masz na myśli zmiany w sterowniku API C# MongoDB po uaktualnieniu do nowszej wersji sterownika C# MongoDB? –

Powiązane problemy