How to use moq to test MongoDB service level?

I have a service level between my application and the mongo database.

I am trying to build a unit test using moq. I am new to moq, so I started with what I think would be a trivial test.

Verification Code:

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

Where: Settings is a MongoDatabase collection - this is MongoDBDriver.MongoDatabase

I tried this as my 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 get an error "Could not find constructor without parameters" at:

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

The error relates to the MongoCollection object. I did not think he had a constructor.

What can I do to run my test?

+7
source share
2 answers

this question is most likely related to: How do I make fun of MongoDB objects to test my data models?

Anyway, here is the minimum Moq configuration required for bullying

  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; 

In any case, as I mentioned in a related question, this may not be acceptable if any of MongoDriver's internal work changes.

+7
source

I am not familiar with MongoDbDriver.MongoDatabase, but if it works the way I think, then you cannot mock it directly. You need to drop the MongoDB passcode and mock it. This will be the actual unit test. eg.

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

Now in your code you enter IMONoDBRepository (using any DI method you like) and your code will look something like this:

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

And finally, your unit test:

 [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 } 
+3
source

All Articles