How do I mock MongoDB objects to test my data models?
I'm using the following logic (MOQ) to attempt to mock out the MongoDB csharp driver objects:
var svr = new Mock<MongoServer>(new MongoServerSettings());
var db = new Mock<MongoDatabase>(svr.Object, new MongoDatabaseSettings("hf_test",
new MongoCredentials("hf_test", "hf_pass"), GuidRepresentation.Standard,
SafeMode.False, false));
When I call db.Object, MOQ attempts to create an instance of my mock MongoDatabase, but it fails with a null-reference exception.
Note: I'm thinking of making an IMongoCollection interface, and wrapping MongoCollection in an instance of it. Then, I can simply mock that out... But th开发者_开发技巧at seems like a whole lot of unnecessary work.
I ended up creating my own interfaces which were basically shallow wrappers on top of the Mongo objects. I can mock these interfaces out, and at least test that the proper indices and filters are in my DAL queries.
this is probably no longer actual (and API might have been changed to be a bit more mock friendly), but here is how it can be done (using Moq):
var message = string.Empty;
var server = new Mock<MongoServer>(new MongoServerSettings());
server.Setup(s => s.IsDatabaseNameValid(It.IsAny<string>(), out message)).Returns(true);
var database = new Mock<MongoDatabase>(server.Object, "test", new MongoDatabaseSettings()
{
GuidRepresentation = MongoDB.Bson.GuidRepresentation.Standard,
ReadEncoding = new UTF8Encoding(),
ReadPreference = new ReadPreference(),
WriteConcern = new WriteConcern(),
WriteEncoding = new UTF8Encoding()
});
var mockedDatabase = database.Object;
Main problem here is, that MongoDatabase object calls method from MongoServer inside it's constructor to check, if name of database complies with rules.
Another issue is, that MongoDatabaseSettings should be initialized with all the values (since MongoDatabase constructor tries to check these against defaults provided from server).
Biggest issue is, that this mocking code might fall apart when new release of c# driver is released :). So writing wrappers on top of Mongo might be actually best fit.
You could try: https://github.com/razonrus/mongo-infrastructure, which aims to be a small library for mocking mongo collection objects for testing purposes. Repository contains sample tests with mocking mongo objects.
Setup mock object in test:
var mongoInitializer = new MockMongoWrapper<IMongoInitializer>()
.SetupDatabase(x => x.SampleDb, x => x
.SetupCollection<User>()
.SetupCollection<Article>(
m => m.Setup(c => c.FindOneById("")).Returns(CreateArticle())))
.SetupDatabase(x => x.LogDb,
x => x.SetupCollection<Log>())
.Object;
精彩评论