如何在C#中使用NUnit编写存根方法

Smi*_*mit 9 c# testing nunit stub

我有2个班:

  • FirstDeep.cs
  • SecondDeep.cs

    我做了简单的代码例如:


class FirstDeep
    {
        public FirstDeep() { }

        public string AddA(string str)
        {
            SecondDeep sd = new SecondDeep();
            bool flag = sd.SomethingToDo(str);

            if (flag == true)
                str = string.Concat(str, "AAA");
            else
                str = string.Concat(str, "BBB");

            return str;
        }
    }

class SecondDeep
    {
        public bool SomethingToDo(string str)
        {
            bool flag = false;
            if (str.Length < 10)
            {
                //todo something in DB, and after that flag should be TRUE
            }
            return flag;
        }
    }
Run Code Online (Sandbox Code Playgroud)

然后我想为方法"AddA"编写单元测试:

class Tests
    {
        [Test]
        public void AddATest()
        {
            string expected = "ABCAAA";

            FirstDeep fd = new FirstDeep();
            string res = fd.AddA("ABC");

            Assert.AreEqual(expected, res);
        }
    }
Run Code Online (Sandbox Code Playgroud)

之后我遇到了麻烦,我不知道在我的Test类中为SomethingToDo方法编写存根是否正确.我总是假的.我应该返回TRUE.但是怎么样?

Mar*_*age 11

允许您编写存根的好方法是使用依赖注入.FirstDeep取决于SecondDeep您的测试,您希望SecondDeep用存根替换.

首先通过提取接口来更改现有代码SecondDeep,然后将其注入FirstDeep构造函数中:

interface ISecondDeep {

  Boolean SomethingToDo(String str);

}

class SecondDeep : ISecondDeep { ... }

class FirstDeep {

  readonly ISecondDeep secondDeep;

  public FirstDeep(ISecondDeep secondDeep) {
    this.secondDeep = secondDeep;
  }

  public String AddA(String str) {   
    var flag = this.secondDeep.SomethingToDo(str);
    ...
  }

}
Run Code Online (Sandbox Code Playgroud)

请注意,FirstDeep不再创建SecondDeep实例.而是在构造函数中注入实例.

在您的测试中,您可以为始终返回true的ISecondDeep位置创建存根SomethingToDo:

class SecondDeepStub : ISecondDeep {

  public Boolean SomethingToDo(String str) {
    return true;
  }

}
Run Code Online (Sandbox Code Playgroud)

在测试中,您使用存根:

var firstDeep = new FirstDeep(new SecondDeepStub());
Run Code Online (Sandbox Code Playgroud)

在生产代码中,您使用"真实" SecondDeep:

var firstDeep = new FirstDeep(new SecondDeep());
Run Code Online (Sandbox Code Playgroud)

使用依赖注入容器和存根框架可以使这很容易.

如果您不想重写代码,可以使用框架拦截Microsoft Moles等调用.在下一版本的Visual Studio中,Fakes Framework中将提供类似的技术.