2012-11-06 15 views
7

Ho un livello di servizio tra la mia app e il database mongo.Come utilizzerei moq per testare un livello di servizio MongoDB?

Sto provando a costruire un test di unità usando moq Sono abbastanza nuovo a moq così ho iniziato con quello che pensavo sarebbe stato un banale test.

Codice di prova:

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

Dove: Impostazioni è una raccolta MongoDatabase è un MongoDBDriver.MongoDatabase

Ho provato questo come il mio test:

[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 ricevo un errore di "Impossibile trovare un costruttore senza parametri" a:

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

L'errore si riferisce all'oggetto MongoCollection. Non pensavo che avesse un costruttore.

Cosa posso fare per eseguire il test?

+0

Donot mock, 'var collection = new Mock >();' e prova –

+1

Mi dispiace, non capisco cosa stai suggerendo. – Richard210363

risposta

3

Non ho familiarità con MongoDbDriver.MongoDatabase, ma se funziona come penso, non è possibile prendere in giro direttamente. È necessario astrarre il codice di accesso MongoDB e deriderlo. Quello sarebbe un test unitario reale. per esempio.

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

Ora, nel codice, si inietta un IMongoDBRepository (usando qualsiasi metodo che ti piace DI) e il codice sarebbe simile a questa:

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

E infine il test di unità:

[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

Questo mi ha dato alcune cose da considerare ma non funzionerà come è. Non è possibile iniettare un oggetto IMongoDBRepository nel metodo. Il codice deve utilizzare un MongoDatabase non un IMongoDBRepository poiché deve leggere un vero database durante l'esecuzione. – Richard210363

+0

Inoltre, MongoDatabase.GetCollection (nome); non può essere eseguito poiché GetCollection non è un metodo statico. Userò l'idea di base e vedrò se riesco a farlo funzionare. – Richard210363

7

questa domanda è molto probabilmente legato a: How do I mock MongoDB objects to test my data models?

In ogni caso, il suo e è configurazione Moq minima richiesta per deridere

 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; 

Comunque, come accennato in questione è collegato, questo potrebbe non essere utile quando qualsiasi funzionamento interno del cambiamento MongoDriver.

+0

Dov'è il codice per 'collection'? – zsong

+2

Sembra mancare ... 'var collection = new Mock > (database.Object," COLLECTIONNAME ", collectionSettings);' e alcune impostazioni di raccolta appropriate. –

+0

Potresti per favore approfondire cosa intendi per "inner-working" di MongoDB Driver change? Intendi le modifiche al driver MongoDB API C# quando esegui l'aggiornamento a una versione più recente del driver C# MongoDB? –

Problemi correlati