Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Mock IMongoCollection.Find using Moq

I am struggling in mocking IMongoCollection.Find method using Moq for my unit tests.

What I tried:

  Mock<IMongoCollection<Person>> mockIMongoCollection = new Mock<IMongoCollection<Person>>();
  mockIMongoCollection.SetupAllProperties();
  mockIMongoCollection
            .Setup(x => x.Find(
                It.IsAny<FilterDefinition<Person>>(),
                It.IsAny<FindOptions>()))
            .Returns();

The thing is whatever I try to return using Returns(), it is not working, I expect to be able to return something convertible to List<Person> and I can't mock or create an instance of IFindFluent<Person,Person> as suggested by return type of Find method.

like image 866
Yahya Hussein Avatar asked Jul 19 '18 08:07

Yahya Hussein


People also ask

How do you mock a method in Moq?

First, we instantiate the FakeDbArticleMock class and indicate which setup we want to use for this test. Then, it is necessary to instantiate the repository we want to test and inject the mock instance into it. Finally, we call the method we are testing and assert the results.

What can be mocked with Moq?

You can use Moq to create mock objects that simulate or mimic a real object. Moq can be used to mock both classes and interfaces.

Can you mock a private method Moq?

Moq supports mocking protected methods. Changing the methods to protected , instead of private , would allow you to mock their implementation.

What is Moq mocking framework?

Moq is a mocking framework built to facilitate the testing of components with dependencies. As shown earlier, dealing with dependencies could be cumbersome because it requires the creation of test doubles like fakes. Moq makes the creation of fakes redundant by using dynamically generated types.


1 Answers

Maby this will help you.

I had to Mock such query:

 var queryRecords = await queryCollection
                .Find(filters)
                .Project(projection)
                .Skip(queryCriteria.Skip)
                .Limit(queryCriteria.Limit)
                .Sort(sort);

to do that I created an abstraction for MongoCollection to handle mongo queries.

public interface IFakeMongoCollection : IMongoCollection<BsonDocument>
{
    IFindFluent<BsonDocument, BsonDocument> Find(FilterDefinition<BsonDocument> filter, FindOptions options);

    IFindFluent<BsonDocument, BsonDocument> Project(ProjectionDefinition<BsonDocument, BsonDocument> projection);

    IFindFluent<BsonDocument, BsonDocument> Skip(int skip);

    IFindFluent<BsonDocument, BsonDocument> Limit(int limit);

    IFindFluent<BsonDocument, BsonDocument> Sort(SortDefinition<BsonDocument> sort);
}

So my tests setup looks like this

[TestFixture]
class QueryControllerTests
{
    private IOptions<MongoSettings> _mongoSettings;
    private QueryController _queryController;
    private Mock<IFakeMongoCollection > _fakeMongoCollection;
    private Mock<IMongoDatabase> _fakeMongoDatabase;
    private Mock<IMongoContext> _fakeMongoContext;
    private Mock<IFindFluent<BsonDocument, BsonDocument>> _fakeCollectionResult;

    [OneTimeSetUp]
    public void Setup()
    {
        _fakeMongoCollection = new Mock<IFakeMongoCollection >();
        _fakeCollectionResult = new Mock<IFindFluent<BsonDocument, BsonDocument>>(
        _fakeMongoDatabase = new Mock<IMongoDatabase>();
        _fakeMongoDatabase
            .Setup(_ => _.GetCollection<BsonDocument>("Test", It.IsAny<MongoCollectionSettings>()))
            .Returns(_fakeMongoCollection.Object);

        _fakeMongoContext = new Mock<IMongoContext>();
        _fakeMongoContext.Setup(_ => _.GetConnection()).Returns(_fakeMongoDatabase.Object);        
        var configuration = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json", false)
            .Build();
        _mongoSettings = Options.Create(configuration.GetSection("MongoConnection").Get<MongoSettings>());
        _queryController = new QueryController(_mongoSettings, _fakeMongoContext.Object);
    }
}

I hope it helps.

like image 114
Maciejek Avatar answered Sep 30 '22 06:09

Maciejek