消除嵌套(类)单元测试中的重复代码

时间:2016-03-17 18:56:51

标签: c# unit-testing nunit

所以我在NUnit中进行了一些单元测试。测试具有类似于RSpec / Jasmine测试的结构 - 一堆具有继承性的嵌套类,用于传递字段。

以下是样本:

[TestFixture]
class ControllerTests
{
    private Controller _controller;

    [SetUp]
    public void Setup()
    {
        _controller = new Controller();
    }

    private class WhenUserIdExistsInSession : ControllerTests
    {
        [SetUp]
        public new void Setup()
        {
            //Preconditions...
        }

        private class WhenUserExistsInDb : WhenUserIdExistsInSession
        {
            [SetUp]
            public new void Setup()
            {
                //Preconditions...
            }

            private class WhenCompanyIdExistsInSession : WhenUserExistsInDb
            {
                [SetUp]
                public new void Setup()
                {
                    //Preconditions...
                }

                private class WhenCompanyExistsInDb : WhenCompanyIdExistsInSession
                {
                    [SetUp]
                    public new void Setup()
                    {
                        //Preconditions...
                    }

                    private class WhenCompanyIsKindaSpecial : WhenCompanyExistsInDb
                    {
                        [SetUp]
                        public new void Setup()
                        {
                            //Preconditions...
                        }

                        [Test]
                        public void SomeGranularUnitTestForReport_1()
                        {
                            _controller.GetCompanyReport();
                            //Some stuff.. 
                        }

                        [Test]
                        public void SomeGranularUnitTestForReport_2()
                        {
                            _controller.GetCompanyReport();
                            //Some stuff.. 
                        }

                        [Test]
                        public void SomeGranularUnitTestForReport_3()
                        {
                            _controller.GetCompanyReport();
                            //Some stuff.. 
                        }
                    }

                    private class WhenCompanyIsTotallyNormal : WhenCompanyExistsInDb
                    {
                        [SetUp]
                        public new void Setup()
                        {
                            //Preconditions...
                        }

                        [Test]
                        public void SomeGranularUnitTestForReport_1()
                        {
                            _controller.GetCompanyReport();
                            //Some stuff.. 
                        }

                        [Test]
                        public void SomeGranularUnitTestForReport_2()
                        {
                            _controller.GetCompanyReport();
                            //Some stuff.. 
                        }

                        [Test]
                        public void SomeGranularUnitTestForReport_3()
                        {
                            _controller.GetCompanyReport();
                            //Some stuff.. 
                        }
                    }
                }
            }
        }
    }
}

这可能看起来像一个小混乱所以这里是来自R#的截图: Image here

正如您所看到的,有很多重复的测试:

  • SomeGranularUnitTestForReport_1
  • SomeGranularUnitTestForReport_2
  • SomeGranularUnitTestForReport_3

任何人都知道如何将这些测试提取到一个地方并保持R#/ NUnit以查看原始结构?

1 个答案:

答案 0 :(得分:0)

您可以尝试使用此模式将测试提取到一个位置。

public abstract class ContextBase
{
    protected virtual void Act()
    {
    }

    protected virtual void Arrange()
    {
    }

    protected virtual void Cleanup()
    {
    }

    [TearDown]
    public void TestCleanup()
    {
        this.Cleanup();
    }

    [SetUp]
    public void TestInit()
    {
        this.Arrange();
        this.Act();
    }
}

public class ControllerTests : ContextBase
{
    private Controller _controller;

    protected override void Arrange()
    {
        _controller = new Controller();
    }

    private class WhenUserIdExistsInSession : ControllerTests
    {
        protected override void Arrange()
        {
            base.Arrange();

            //Preconditions...
        }

        private class WhenUserExistsInDb : WhenUserIdExistsInSession
        {
            protected override void Arrange()
            {
                base.Arrange();

                //Preconditions...
            }

            private class WhenCompanyIdExistsInSession : WhenUserExistsInDb
            {
                protected override void Arrange()
                {
                    base.Arrange();

                    //Preconditions...
                }

                private abstract class WhenCompanyExistsInDb : WhenCompanyIdExistsInSession
                {
                    protected override void Arrange()
                    {
                        base.Arrange();

                        //Preconditions...
                    }

                    protected override void Act()
                    {
                        _controller.GetCompanyReport();
                    }

                    [Test]
                    public void SomeGranularUnitTestForReport_1()
                    {
                        //Some stuff.. 
                    }

                    [Test]
                    public void SomeGranularUnitTestForReport_2()
                    {
                        //Some stuff.. 
                    }

                    [Test]
                    public void SomeGranularUnitTestForReport_3()
                    {
                        //Some stuff.. 
                    }

                    [TestFixture]
                    public class WhenCompanyIsKindaSpecial : WhenCompanyExistsInDb
                    {
                        protected override void Arrange()
                        {
                            base.Arrange();

                            //Preconditions...
                        }
                    }

                    [TestFixture]
                    public class WhenCompanyIsTotallyNormal : WhenCompanyExistsInDb
                    {
                        protected override void Arrange()
                        {
                            base.Arrange();

                            //Preconditions...
                        }
                    }
                }
            }
        }
    }
}

然而,它不会让R#看到原始的嵌套结构。