C# Rhino.Mocks - 如何在不重复自己的情况下编写测试代码?

标签 c# unit-testing rhino-mocks

我希望在我的 Rhino.Mocks 单元测试中删除所有依赖项,但我最终还是重复了一遍。随着依赖项的数量不断增加,我需要重新访问我现有的单元测试并需要添加依赖项。这是不令人满意的,也是我应该以另一种方式来做的信号。

如果我只是将初始化移动到一个单独的方法,我将所有模拟传递给它,但我什么也没做。

有没有办法初始化然后将 Using(mocks.Record) 作为 lambda 表达式传递给方法?或者你是怎么做到的?!

提前感谢您的任何评论,

安德斯,丹麦

    [Test, Category("UnitTest")]
    public void TestThatApplicationCanExitByDefault()
    {
        var mocks = new MockRepository();

        var workspaceViewModelProvider = mocks.StrictMock<IWorkspaceViewModelProvider>();
        var workspaceRepository = mocks.StrictMock<IWorkspaceService>();
        var userResponseProvider = mocks.StrictMock<IUserResponseProvider>();
        var versionProvider = mocks.StrictMock<IVersionProvider>();
        var eventAggregator = mocks.StrictMock<IEventAggregator>();
        var allowedLegacyImportProvider = mocks.StrictMock<IAllowedLegacyImportProvider>();
        var stateManager = mocks.StrictMock<IStateManager>();
        var currentWorkspaceChangedEvent = mocks.StrictMock<CurrentWorkspaceChangedEvent>();

        using (mocks.Record())
        {
            // constructor fires:
            eventAggregator
                .Stub(x => x.GetEvent<CurrentWorkspaceChangedEvent>())
                .Return(currentWorkspaceChangedEvent);

            currentWorkspaceChangedEvent
                .Stub(x => x.Subscribe(null))
                .IgnoreArguments();
        }

        var target = new MainWindowViewModel(
            workspaceViewModelProvider,
            workspaceRepository,
            userResponseProvider,
            versionProvider, eventAggregator, allowedLegacyImportProvider, stateManager);

        var canAppExit = target.CanAppExit();

        Assert.IsTrue(canAppExit);

        mocks.VerifyAll();
    }


    [Test, Category("UnitTest")]
    public void TestThatInsertProjectWorks()
    {
        var mocks = new MockRepository();

        var workspaceViewModelProvider = mocks.StrictMock<IWorkspaceViewModelProvider>();
        var workspaceRepository = mocks.StrictMock<IWorkspaceService>();
        var userResponseProvider = mocks.StrictMock<IUserResponseProvider>();
        var versionProvider = mocks.StrictMock<IVersionProvider>();
        var eventAggregator = mocks.StrictMock<IEventAggregator>();
        var allowedLegacyImportProvider = mocks.StrictMock<IAllowedLegacyImportProvider>();
        var stateManager = mocks.StrictMock<IStateManager>();
        var currentWorkspaceChangedEvent = mocks.StrictMock<CurrentWorkspaceChangedEvent>();
        var workspaceViewModel = mocks.StrictMock<IWorkspaceViewModel>();

        using (mocks.Record())
        {
            // constructor fires:
            eventAggregator
                .Stub(x => x.GetEvent<CurrentWorkspaceChangedEvent>())
                .Return(currentWorkspaceChangedEvent);

            currentWorkspaceChangedEvent
                .Stub(x => x.Subscribe(null))
                .IgnoreArguments();

            workspaceViewModelProvider
                .Stub(x => x.GetViewModel())
                .Return(workspaceViewModel);

            workspaceViewModel
                .Stub(x => x.InsertProject());
        }

        var target = new MainWindowViewModel(
            workspaceViewModelProvider,
            workspaceRepository,
            userResponseProvider,
            versionProvider, eventAggregator, allowedLegacyImportProvider, stateManager);

        target.InsertProject();

        mocks.VerifyAll();
    }

最佳答案

我倾向于使用一个辅助方法来负责构建我的模拟,这个方法需要一个 lambda。然后 lambda 可以将模拟传达给测试。我有测试辅助方法的重载以形成 API,从而限制可用于测试的模拟。通过这种方式,模拟构建可以集中进行,从而最大限度地减少测试中的依赖关系。

举个例子就更明显了。这个用的是Moq,但是技术一般。

    private static void RunTest(Action<IThing1> test)
    {
        RunTest(test: (thing1, thing2, thing3) => test(thing1));
    }

    private static void RunTest(Action<IThing1, IThing2> test)
    {
        RunTest(test: (thing1, thing2, thing3) => test(thing1, thing2));
    }

    private static void RunTest(Action<IThing1, IThing2, IThing3> test)
    {
        IThing1 thing1 = new Mock<IThing1>().Object;
        IThing2 thing2 = new Mock<IThing2>().Object;
        IThing3 thing3 = new Mock<IThing3>().Object;

        test(thing1, thing2, thing3);
    }

    [Test]
    public void do_some_stuff_to_a_thing()
    {
        RunTest(test: thing1 => {
            //Do some testing....
        });
    }

    [Test]
    public void do_some_stuff_to_things()
    {
        RunTest(test: (thing1, thing2) => {
            //Do some testing....
        });
    }

关于C# Rhino.Mocks - 如何在不重复自己的情况下编写测试代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4735297/

相关文章:

c# - 如何在 Xamarin.Forms 中检测 Stacklayout 的左滑动和右滑动?

.net - 什么是好的策略?在没有默认 Virtual 的情况下使用 C# 中的 Mock 进行测试

c# - Rhino Mock 执行 yield return

适用于 Windows(桌面)和 Windows Phone 8 的 C# MVVM 应用程序框架

c# - 在 Internet Explorer 10 中从 Javascript 调用 C# BHO 方法(发布预览)

unit-testing - 测试 MongooseJs 验证

c - C 中的左值、右值和数组初始化

c# - 如何检查 Action 对 View() 的调用没有抛出异常?

c# - 我如何模拟 IQueryable<T>

c# - SocketException : An existing connection was forcibly closed under IIS 7, 但在 IIS 6 下正常