如何在单元测试中使用Mock对象并仍使用代码覆盖率?

mez*_*oid 16 .net c# unit-testing code-coverage moq

现在我开始将Mock对象的概念引入我的单元测试中.特别是我正在使用Moq框架.但是,我注意到的一件事是突然我使用这个框架测试的类显示代码覆盖率为0%.

现在我明白了,因为我只是在嘲笑这个类,它没有运行实际的类本身....但是我如何编写这些测试并让Code Coverage返回准确的结果呢?我是否必须编写一组使用Mocks的测试和一组直接实例化该类的测试.

也许我在没有意识到的情况下做错了什么?

这是我尝试单元测试一个名为"MyClass"的类的示例:

using Moq;
using NUnitFramework;

namespace MyNameSpace
{
    [TestFixture]
    public class MyClassTests
    {

        [Test]
        public void TestGetSomeString()
        {
            const string EXPECTED_STRING = "Some String!";

            Mock<MyClass> myMock = new Mock<MyClass>();
            myMock.Expect(m => m.GetSomeString()).Returns(EXPECTED_STRING);

            string someString = myMock.Object.GetSomeString();

            Assert.AreEqual(EXPECTED_STRING, someString);
            myMock.VerifyAll();

        }

    }

    public class MyClass
    {
        public virtual string GetSomeString()
        {
            return "Hello World!";
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

有谁知道我应该采取哪些不同的做法?

Nat*_*n W 17

您没有正确使用模拟对象.当您使用模拟对象时,您打算测试代码如何与其他对象交互而不实际使用真实对象.请参阅以下代码:

using Moq;
using NUnitFramework;

namespace MyNameSpace
    {
        [TestFixture]
        public class MyClassTests
        {

            [Test]
            public void TestGetSomeString()
            {
                const string EXPECTED_STRING = "Some String!";

                Mock<IDependance> myMock = new Mock<IDependance>();
                myMock.Expect(m => m.GiveMeAString()).Returns("Hello World");

                MyClass myobject = new MyClass();

                string someString = myobject.GetSomeString(myMock.Object);

                Assert.AreEqual(EXPECTED_STRING, someString);
                myMock.VerifyAll();

            }

        }

        public class MyClass
        {

            public virtual string GetSomeString(IDependance objectThatITalkTo)
            {
                return objectThatITalkTo.GiveMeAString();
            }
        }

        public interface IDependance
        {
            string GiveMeAString();
        }
    }
Run Code Online (Sandbox Code Playgroud)

当你的代码只返回一个没有任何逻辑的字符串时,它看起来并没有做任何有用的事情.

如果你的GetSomeString()方法做了一些逻辑可能会改变输出字符串的结果,取决于来自的返回,真正的力量来了IDependdance .GiveMeAString()方法,然后您可以看到您的方法如何处理从IDependdance接口发送的错误数据.

就像是:

 public virtual string GetSomeString(IDependance objectThatITalkTo)
 {
     if (objectThatITalkTo.GiveMeAString() == "Hello World")
         return "Hi";
     return null;
 }
Run Code Online (Sandbox Code Playgroud)

现在,如果您在测试中有这一行:

myMock.Expect(m => m.GiveMeAString()).Returns(null);
Run Code Online (Sandbox Code Playgroud)

您的GetSomeString()方法会发生什么?


Ale*_*ček 8

最大的错误是嘲笑被测系统(SUT),你测试别的东西.你应该只模拟SUT依赖项.