正确地模拟泛型方法

本文关键字:泛型方法 模拟 正确地 | 更新日期: 2023-09-27 18:12:02

对Moq和mock不熟悉。测试一个具有通用RepositoryFactory并使用它的几个存储库的类。我应该这样初始化还是有更好的方法?

Mock<IRepositoryFactory> factory;
        Mock<IRepository<User>> userRepository;
        Mock<IRepository<Role>> roleRepository;
        Mock<IRepository<Meeting>> meetingRepository;
        [TestInitialize()]
        public void MyTestInitialize()
        {
            meetingRepository = new Mock<IRepository<Meeting>>();
            //some meeting setup
            userRepository = new Mock<IRepository<User>>();
            //some user setup
            roleRepository = new Mock<IRepository<Role>>();
            //some role setup
            factory = new Mock<IRepositoryFactory>();
            factory.Setup(f => f.CreateRepository<Meeting>()).Returns(meetingRepository.Object);
            factory.Setup(f => f.CreateRepository<User>()).Returns(userRepository.Object);
            factory.Setup(f => f.CreateRepository<Role>()).Returns(roleRepository.Object);

请注意,我可以有更多。

我在我的初始化方法中都做了但是我想我应该单独做或者别的什么

正确地模拟泛型方法

考虑到每个T的存储库设置可能不同,我不知道如何设置f => f.CreateRepository<T>()。除此之外,您还可以使用功能规范(请参阅此博客文章),这会使事情变得更清晰。

对于您的示例,它看起来像这样:

var factory = Mock.Of<IRepositoryFactory>(
    x => 
    x.CreateRepository<Meeting>() == Mock.Of<IRepository<Meeting>>() &&
    x.CreateRepository<Role>() == Mock.Of<IRepository<Role>>() &&
    x.CreateRepository<User>() == Mock.Of<IRepository<User>>()
    );

技术上,我看不出你的代码有什么问题。

然而,有点令人担忧的是,你甚至还没有开始在你想要测试的类上工作,并且已经有4个mock,并且"可以有更多"。听起来好像有很多陷阱。

最重要的是,如果我对[TestInitialize]的理解是正确的,这意味着对于该类中的每个测试,每个存储库都将以相同的方式设置。这可能会妨碍在不同条件下指定测试。

也许您应该考虑避免[TestInitialize],并在每个测试方法中设置您需要的存储库,具体到您想要断言的内容-并按照bdd风格逐步将每个存储库的设置提取到共享方法中:"Given_User_Of_Type_VIP()"返回具有VIP设置类型用户的存储库。