2012-11-06 3 views
7

Ich habe eine Service-Schicht zwischen meiner App und der Mongo-Datenbank.Wie würde ich moq verwenden, um eine MongoDB-Service-Schicht zu testen?

Ich versuche, einen Komponententest mit moq zu bauen Ich bin ziemlich neu zu moq, also begann ich mit, was ich dachte, wäre ein trivialer Test.

-Code zu testen:

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

Wo: Einstellungen eine Collection ist MongoDatabase ist ein MongoDBDriver.MongoDatabase

ich dies als meinen Test habe versucht:

[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 bekomme einen Fehler von "Konnte keinen parameterlosen Konstruktor finden" unter:

mongoDatabase.Setup (f => f.GetCollection (MongoCollections.Settings)). Rückgabe (collection.Object);

Der Fehler bezieht sich auf das MongoCollection-Objekt. Ich dachte nicht, dass es einen Konstrukteur gibt.

Was kann ich tun, um meinen Test zu starten?

+0

Donot Mock, 'var Sammlung = neue Mock >();' und versuchen –

+1

Es tut mir leid, ich verstehe nicht, was Sie vorschlagen. – Richard210363

Antwort

3

Ich bin nicht vertraut mit der MongoDbDriver.MongoDatabase, aber wenn es funktioniert, wie ich denke, es ist, dann können Sie es nicht direkt verspotten. Sie müssen den MongoDB-Zugriffscode abstrahieren und sich darüber lustig machen. Das wäre ein echter Unit Test. z.B.

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

nun in Ihrem Code, injizieren Sie ein IMongoDBRepository (verwenden Sie das DI-Methode Sie möchten) und Ihr Code würde in etwa so aussieht:

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

Und schließlich Ihr Gerät zu testen:

[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

Dies hat mir einige Dinge in Betracht gezogen, aber wird nicht so funktionieren, wie es ist. Sie können kein IMongoDBRepository-Objekt in die Methode einfügen. Der Code muss eine MongoDatabase und kein IMongoDBRepository verwenden, da er eine echte Datenbank lesen muss, wenn er ausgeführt wird. – Richard210363

+0

Auch MongoDatabase.GetCollection (Name); nicht möglich, da GetCollection keine statische Methode ist. Ich werde die Grundidee verwenden und sehen, ob ich es zum Funktionieren bringen kann. – Richard210363

7

diese Frage, die meisten wahrscheinlich im Zusammenhang mit: How do I mock MongoDB objects to test my data models?

Wie auch immer, sie e ist minimal Moq Konfiguration

 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; 

Auf jeden Fall verspotten erforderlich, wie ich in verknüpfte Frage erwähnte, ist dies nicht sinnvoll sein könnte, wenn jeder inneren Funktionsweise von MongoDriver ändern.

+0

Wo ist der Code für "Sammlung"? – zsong

+2

Scheint zu fehlen ... 'var collection = neuer Mock > (database.Object," COLLECTIONNAME ", collectionSettings);' und einige passende collectionSettings. –

+0

Könntest du bitte erläutern, was du unter innerer Arbeit von MongoDB Driver Change verstehst? Meinst du die Änderungen an API C# MongoDB-Treiber, wenn Sie auf eine neuere Version des C# MongoDB-Treibers aktualisieren? –

Verwandte Themen