编程语言
首页 > 编程语言> > C#Rhino.Mocks-如何编写测试代码而不重复自己?

C#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....
        });
    }

标签:unit-testing,c,rhino-mocks
来源: https://codeday.me/bug/20191023/1914062.html