正确模拟泛型方法

发布于 2024-12-12 01:40:14 字数 1167 浏览 0 评论 0原文

一般来说,对于最小起订量和模拟来说是新的。测试一个具有通用 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);

请注意,我可以有更多。

在这里,我在初始化方法中完成了这一切,但我想我应该单独执行它或也执行其他操作。

New to Moq and Mocking in general. Testing a class that has a generic RepositoryFactory and uses several of it's repositories. Should I initialize like this or is there some better way?

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

Note that I could have mcuh more.

here I'm doing it all in my initialize method but guess I should do it individually or something also.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

因为看清所以看轻 2024-12-19 01:40:14

我不知道如何设置 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>>()
    );

I don't know of a way to set up f => f.CreateRepository<T>(), considering that your repository setup could be different for each T. Aside from that, you can use functional specifications (see this blog post), which makes things a bit cleaner.

For your example, it would look like this:

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>>()
    );
一桥轻雨一伞开 2024-12-19 01:40:14

从技术上讲,我没有发现您的代码有问题。

然而,有点令人担忧的是,您甚至还没有开始处理您想要测试的课程,并且已经有 4 个模拟,并且“还可以有更多”。听起来需要进行大量的设置。

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

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

Technically, I don't see a problem with your code.

However, it's a bit worrisome that you haven't even started to work on the class you want to test, and already have 4 mocks, and "could have much more". It sounds like an awful lot of setup.

On top of that, if my understanding of [TestInitialize] is correct, it means that for every test in this class, every repository will be setup the same way. That's probably going to get in the way of specifying tests with different conditions.

Maybe you should consider avoiding [TestInitialize], and setup the repositories you need in each test method, specific to what you want to assert - and progressively extract the setup for each repository into shared methods, following a BDD-style : "Given_User_Of_Type_VIP()" returns a Repository with a user of type VIP setup.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文