如何使用 FakeItEasy 验证 FindOneAndUpdateAsync 方法 运行 以对抗伪造的 MongoCollection?
How to use FakeItEasy to verify FindOneAndUpdateAsync method ran Against faked MongoCollection?
我正在使用 FakeItEasy
库进行单元测试,并尝试为 mongo 更新语句编写单元测试,并验证是否使用 [=17] 调用了 FindOneAndUpdateAsync
方法=].
我创建了一个单元测试,它将伪造 dbcontext
class,使用它来生成 collection,然后调用将 运行 更新的方法声明反对造假collection。当我在调试模式下 运行 测试时,它命中了 FindOneAndUpdateAsync
方法,但是 MustHaveHappened()
结果显示该方法没有 运行 对抗伪造的 collection.
有没有一种方法可以使用 FakeItEasy
来检测 FindOneAndUpdateAsync
方法 运行 当 collection 被 运行 反对时伪造的?
失败测试的错误消息
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 的接口
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
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
调用的原因,即使您在调试时看到了对 something 的调用。有时在这些令人困惑的情况下,检查测试中对象的身份 (ReferenceEquals) 是值得的。
使用了新的 Fake,因为您配置了 fakeDbContext
两次。您的第二个电话应该在要求 IMongoCollection<Fruit>
:
时将 fakeMongoCollection
配置为 return 本身
A.CallTo(fakeDbContext).WithReturnType<IMongoCollection<Fruit>>()
.Returns(fakeMongoCollection);
→
A.CallTo(fakeMongoCollection).WithReturnType<IMongoCollection<Fruit>>()
.Returns(fakeMongoCollection);
我正在使用 FakeItEasy
库进行单元测试,并尝试为 mongo 更新语句编写单元测试,并验证是否使用 [=17] 调用了 FindOneAndUpdateAsync
方法=].
我创建了一个单元测试,它将伪造 dbcontext
class,使用它来生成 collection,然后调用将 运行 更新的方法声明反对造假collection。当我在调试模式下 运行 测试时,它命中了 FindOneAndUpdateAsync
方法,但是 MustHaveHappened()
结果显示该方法没有 运行 对抗伪造的 collection.
有没有一种方法可以使用 FakeItEasy
来检测 FindOneAndUpdateAsync
方法 运行 当 collection 被 运行 反对时伪造的?
失败测试的错误消息
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 的接口
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
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
调用的原因,即使您在调试时看到了对 something 的调用。有时在这些令人困惑的情况下,检查测试中对象的身份 (ReferenceEquals) 是值得的。
使用了新的 Fake,因为您配置了 fakeDbContext
两次。您的第二个电话应该在要求 IMongoCollection<Fruit>
:
fakeMongoCollection
配置为 return 本身
A.CallTo(fakeDbContext).WithReturnType<IMongoCollection<Fruit>>()
.Returns(fakeMongoCollection);
→
A.CallTo(fakeMongoCollection).WithReturnType<IMongoCollection<Fruit>>()
.Returns(fakeMongoCollection);