如何使用FakeItEasy验证FindOneAndUpdateAsync方法是否针对伪造的MongoCollection运行?

时间:2018-07-18 14:27:48

标签: c# mongodb unit-testing fakeiteasy

我正在使用Export-PfxCertificate库进行单元测试,并尝试为mongo update语句编写单元测试,并验证是否使用FakeItEasy调用了FindOneAndUpdateAsync方法。

我创建了一个单元测试,该单元测试将伪造MustHaveHappened()类,使用该类来生成集合,然后针对伪造的集合调用将运行update语句的方法。当我在调试模式下运行测试时,它遇到的是dbcontext方法,但是FindOneAndUpdateAsync的结果表明该方法未针对伪造的集合运行。

是否有一种使用MustHaveHappened()的方法来检测FakeItEasy方法是否在伪造运行的集合时被伪造了?

测试失败的错误消息

  

以下呼叫的断言失败:       对假对象的任何调用。         其中x =>(x.Method.Name ==“ FindOneAndUpdateAsync”)     期望一次或多次找到它,但在调用中找不到它:       1:MongoDB.Driver.IMongoCollection`1 [ConsoleApp3.Fruit] .WithWriteConcern(writeConcern:{w:“ majority”})

使用FakeItEasy进行单元测试

FindOneAndUpdateAsync

DBContext的接口

    [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();
    }

水果实体

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; }
}

1 个答案:

答案 0 :(得分:3)

问题在于WithWriteConcern的结果不是fakeMongoCollection。这就是为什么FakeItEasy没有看到FindOneAndUpdateAsync调用的原因,即使您在调试时看到的是在 something 上进行的。有时在这些令人困惑的情况下,值得检查测试中对象的身份(ReferenceEquals)。

使用新的Fake,因为您配置了两次fakeDbContext。您的第二个呼叫应将fakeMongoCollection配置为在要求输入IMongoCollection<Fruit>时返回自身:

A.CallTo(fakeDbContext).WithReturnType<IMongoCollection<Fruit>>()
    .Returns(fakeMongoCollection);

A.CallTo(fakeMongoCollection).WithReturnType<IMongoCollection<Fruit>>()
     .Returns(fakeMongoCollection);