c# - 如何使用 FakeItEasy 验证 FindOneAndUpdateAsync 方法针对伪造的 MongoCollection 运行?

标签 c# mongodb unit-testing fakeiteasy

我正在使用 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/

相关文章:

java - 使用 Spark 和 Java 将问题连接到 MongoDB

mongodb - 如何使用mongo-driver/mongo查找具有多种条件的文档

iphone - 单元测试时为 "Undefined symbols for architecture i386"

c# - 单元测试不会运行 : process is terminated due to StackOverflowException

c# - WPF中如何制作翻页效果?

c# - 如何在javascript中使用.net资源文件

c# - 系统.Data.SqlClient.SqlException : Timeout expired

c# - Windows 服务可以自行停止吗?

mongodb - 将 mongoDB 集群转换为副本集时出错

iphone - 无法在单元测试中设置 NSMutableDictionary 中的值