Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How would I use moq to test a MongoDB service layer?

Tags:

c#

mongodb

moq

I have a service layer between my app and the mongo database.

I'm trying to build a unit test using moq I'm quite new to moq so I started with what I thought would be a trivial test.

Code to test:

    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 Collection MongoDatabase is a MongoDBDriver.MongoDatabase

I've 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'm getting an error of "Could not find a parameterless constructor" at:

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

The error refers to the MongoCollection object. I didn't think it had a constructor.

What can I do to get my test to run?

like image 282
Richard210363 Avatar asked Nov 06 '12 18:11

Richard210363


1 Answers

this question is most probably related to: How do I mock MongoDB objects to test my data models?

Anyway, here is minimal Moq configuration required to 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;

Anyway, as I mentioned in linked question, this might not be useful when any of inner-workings of MongoDriver change.

like image 183
Marian Polacek Avatar answered Oct 05 '22 05:10

Marian Polacek