在隐藏成员时对映射进行单元测试

本文关键字:单元测试 映射 隐藏 成员 | 更新日期: 2023-09-27 18:14:44

我必须测试一个处理给定事件的投影,并将其持久化在只读Mongo数据库上(我使用官方的c# Mongo Driver):

public class MyObjectProjection : IHandleMessages<RegisteredEvent>
{
    private MongoCollection<MyObjectView> _collection;
    private MyObjectView item;
    public MyObjectProjection (MongoDatabase db)
    {
        _collection = db.GetCollection<MyObjectView>("my-object");
    }
    public void Handle(RegisteredEvent message)
    {
        item = new MyObjectView();
        item.Id = message.Id;
        // some code omitted                
        _collection.Save(item);
    }
}

我需要对Handle方法进行单元测试,给定:

    我不想要集成测试。数据库和集合是模拟的,所以save 不是真实的
  • 我只是想测试项目-消息映射
  • 成员是隐藏的,我不想让他们更可见

我应该使用替代解决方案而不是反射或友好组装吗?在这种情况下,最佳实践是什么?现在我的测试是这样的:

    [TestMethod]
    public void TestMethod1()
    {
        // ARRANGE - some code omitted
        databaseMock
            .Setup(x => x.GetCollection<MyObjectView>(It.IsAny<string>()))
            .Returns(collection);
        collectionMock
            .Setup(x => x.Save(It.IsAny<MyObjectView>()))
            .Returns(It.IsAny<WriteConcernResult>);
        // ACT
        var handler = new MyObjectProjection(database);
        handler.Handle(evt);
        // ASSERT
        // nothin' to assert here!
    }

这个工作,但是当Handle方法完成时,我没有什么可以断言的。

在隐藏成员时对映射进行单元测试

在这种情况下的最佳实践是什么?

最佳实践是使成员可见。您需要隐藏成员有什么特别的原因吗?

然后,您可以对传递给Save方法的参数进行断言:

    MyObjectView objectView;
    collectionMock
        .Setup(x => x.Save(It.IsAny<MyObjectView>()))
        .Callback<MyObjectView>((obj) => objectView= obj)
        .Returns(It.IsAny<WriteConcernResult>);
    Assert.That(objectView.Id, Is.EqualTo(evt.Id));
    //assert other properties

那么,您的Handle()方法通过调用Save()方法与集合交互。因此,您可以期望传递给Handle方法的元素具有适当的ID集:

collectionMock.Verify(x=>x.Save(It.Is<MyObjectView>(v => v.Id == 5)), Times.Once,"save should be called with object with Id = 5");

我在这里假设传递给Handle()evt的Id为5。代码没有经过测试,但我认为类似的东西可以做到。