我正在使用 FakeItEasy
库进行单元测试,并尝试为 mongo 更新语句编写单元测试,并验证是否使用 调用了
.FindOneAndUpdateAsync
方法MustHaveHappened()
我已经创建了一个单元测试,它将伪造 dbcontext
类,使用它来生成一个集合,然后调用将针对伪集合运行更新语句的方法。当我在 Debug模式下运行测试时,它命中了 FindOneAndUpdateAsync
方法,但是 MustHaveHappened()
结果显示该方法没有针对伪造的集合运行。
有没有一种方法可以使用 FakeItEasy
来检测 FindOneAndUpdateAsync
方法在其运行所针对的集合也被伪造时运行?
失败测试的错误消息
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" })
使用 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();
}
DBContext 接口(interface)
public interface IDBContext
{
IMongoClient Client { get; }
IMongoDatabase Database { get; }
IMongoCollection<TDocument> GetCollection<TDocument>()
where TDocument : Fruit;
}
水果实体
public class Fruit
{
public ObjectId Id { get; set; }
public string Name { get; set; }
public double Price { get; set; }
public int Quantity { get; set; }
}
水果库类
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)
);
}
最佳答案
问题是 WithWriteConcern
的结果不是 fakeMongoCollection
.这就是 FakeItEasy 没有看到 FindOneAndUpdateAsync
的原因调用,即使您在调试时看到了对某物 的调用。有时在这些令人困惑的情况下,检查测试中对象的身份 (ReferenceEquals) 是值得的。
因为您正在配置 fakeDbContext
,所以使用了一个新的 Fake两次。您的第二个电话应该配置 fakeMongoCollection
当它被要求 IMongoCollection<Fruit>
时返回自己:
A.CallTo(fakeDbContext).WithReturnType<IMongoCollection<Fruit>>()
.Returns(fakeMongoCollection);
→
A.CallTo(fakeMongoCollection).WithReturnType<IMongoCollection<Fruit>>()
.Returns(fakeMongoCollection);
关于c# - 如何使用 FakeItEasy 验证 FindOneAndUpdateAsync 方法针对伪造的 MongoCollection 运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51404602/