正确地模拟通用方法

时间:2011-10-23 17:42:38

标签: c# unit-testing mocking moq

Moq和Mocking的新手。测试具有通用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);

请注意,我可能会有更多。

这里我在初始化方法中做了所有这些,但我猜我应该单独做一些事情或者其他事情。

2 个答案:

答案 0 :(得分:2)

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

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

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

答案 1 :(得分:1)

从技术上讲,我没有看到你的代码有问题。

然而,有点令人担忧的是你甚至没有开始在你想要测试的课程上工作,并且已经有4次嘲讽,并且“可能有更多”。这听起来像是一个非常多的设置。

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

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