I am using the FakeItEasy
library for unit testing and trying to write a unit test for a mongo update statement and verify that the FindOneAndUpdateAsync
method was called using MustHaveHappened()
.
I have created a unit test that will fake the dbcontext
class, use that to generate a collection, then call the method that will run the update statement against the fake collection. When I run the test in debug mode, it is hitting the FindOneAndUpdateAsync
method, however the MustHaveHappened()
result is showing that the method did not run against the faked collection.
Is there a way to use FakeItEasy
to detect that the FindOneAndUpdateAsync
method ran when the collection it is being run against is also being faked?
Error Message from Failed Test
Assertion failed for the following call: Any call made to the fake object. where x => (x.Method.Name == "FindOneAndUpdateAsync") Expected to find it once or more but didn't find it among the calls: 1: MongoDB.Driver.IMongoCollection`1[ConsoleApp3.Fruit].WithWriteConcern(writeConcern: { w : "majority" })
Unit Test Using FakeItEasy
[Fact]
public async Task TestFruitUpdate()
{
IDBContext fakeDbContext = A.Fake<DBContext>();
var fakeMongoCollection = A.Fake<IMongoCollection<Fruit>>();
var fruitEntity = new Fruit()
{
Id = new MongoDB.Bson.ObjectId(),
Name = "Apple",
Price = 2.0,
Quantity = 3,
};
A.CallTo(() => fakeDbContext.GetCollection<Fruit>()).Returns(fakeMongoCollection);
A.CallTo(fakeDbContext).WithReturnType<IMongoCollection<Fruit>>().Returns(fakeMongoCollection);
var repository = new FruitRepository(fakeDbContext);
await repository.UpdateFruitQuantityAsync(fruitEntity);
A.CallTo(fakeMongoCollection).Where(x => x.Method.Name == "FindOneAndUpdateAsync").MustHaveHappened();
}
Interface for DBContext
public interface IDBContext
{
IMongoClient Client { get; }
IMongoDatabase Database { get; }
IMongoCollection<TDocument> GetCollection<TDocument>()
where TDocument : Fruit;
}
Fruit Entity
public class Fruit
{
public ObjectId Id { get; set; }
public string Name { get; set; }
public double Price { get; set; }
public int Quantity { get; set; }
}
Fruit Repository Class
class FruitRepository
{
private readonly IDBContext _dbContext;
public FruitRepository(IDBContext dBContext) =>
_dbContext = dBContext;
public virtual Task UpdateFruitQuantityAsync(Fruit fruitEntity) =>
_dbContext.GetCollection<Fruit>()
.WithWriteConcern(WriteConcern.WMajority)
.FindOneAndUpdateAsync(
Builders<Fruit>.Filter.Eq(j => j.Id, fruitEntity.Id),
Builders<Fruit>.Update.Set(j => j.Quantity, fruitEntity.Quantity)
);
}