C#模拟返回基本方法 [英] c# mock return base method

查看:123
本文介绍了C#模拟返回基本方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用NUnit框架编写单元测试用例以测试我们的代码.

I am writing a unit test case with NUnit framework to test our code.

该代码已引用了第三方库,如下所示:

The code has referenced to 3rd party libraries like below:

class MyClass: BaseClass
{
    public void override FunctionA()
    {
      var a = BaseFunctionB();
    }
}

我们没有BaseClass的源代码,但是BaseFunctionB是非虚拟的.

we don't have sourcecode for BaseClass, but the BaseFunctionB is non-virtual.

我正试图

Setup(x=> x.BaseFunctionB()).Reteruns("my values");

但这是不允许的.

我只想在MyClass中测试FunctionA,我不在乎在BasefunctionB中它是否正确.

I just want to test the FunctionA in MyClass, I don't care whether it's correct in BasefunctionB.

在这种情况下如何测试?

How to test in this case?

---------------------------- 2018-01-03更新------------- -------------------- 我对BaseClass作了一些更新:

----------------------------2018-01-03 updated--------------------------------- I made some update for the BaseClass:

public abstract class BaseClass1//we dont have source code for this class
{
    public int GetValue()
    {
        //do something here
        return 1;//
    }

    public abstract int GenerateOutPut();
}


class abstract class BaseClass2: BaseClass1
{
    public new virtual int GetValue()
    {
        return base.GetValue();
    }
}

class MyClass1: BaseClass2
{
    public override int GenerateOutPut()
    {
        var a = GetValue();
        a += 1;
        return a;
    }
}

class MyClass2: BaseClass2
{
    public override int GenerateOutPut()
    {
        var a = GetValue();
        a -= 1;
        return a;
    }
}

// there are many MyClass
class MyClassN: BaseClass2
{
    public override int GenerateOutPut()
    {
        var a = GetValue();
        //different logic here.
        return a;
    }
}

我制作了一个测试MyClass1的类,如下所示:

i made a class for testing MyClass1 like below:

class TestClass1: MyClass1
{
    public override int GetValue()
    {
        return 100;
    }
}

测试案例如下:

public void TestFunction()
{
    var test = new TestClass1();
    var result = test.GetValue();

    assert.AreEqual(101, result);
}

现在我必须创建许多看起来不太好的TestClas.但是在用尽代码覆盖率方面,我必须做到(我尝试使用模拟对象执行,报告中没有代码覆盖,我猜因为它创建了代理并在代理上运行,所以我创建了同样的东西我自己来测试原始源代码)

Now I have to create many TestClas which looks not good. but in terms of running out code coverage, i have to make it( i try to use mock object to execute, there is no code covered in report, i guess because it create proxy and run it on proxy, so i create the same thing myself to test the original source code)

我有更好的解决方案吗?

Do i have a better solution?

推荐答案

创建第二个基类和新成员以封装第三方依赖关系是一个好主意.它允许您覆盖派生类中的成员.通常,尽量避免嘲笑您不拥有的东西.而是将第三方的依赖关系封装在您控制的抽象后面,以使您能够灵活地模拟/存根/伪造任何所需的行为以进行测试.

Creating the second base class and the new member to encapsulate the 3rd party dependency was a good idea. It allows you to override the member in derived classes. In general try to avoid mocking what you do not own. Instead encapsulate 3rd party dependencies behind an abstraction you control so as to allow you the flexibility to mock/stub/fake any desired behavior for testing.

在您的示例中使用MyClass1

public class MyClass1 : BaseClass2 {
    public override int GenerateOutPut() {
        var a = GetValue();
        a += 1;
        return a;
    }
}

可以执行以下测试,以验证来自被测对象的预期行为.注意Moq允许通过在模拟对象上设置CallBase = true来调用基本成员.

The following test can be done to verify the expected behavior from the subject under test. Note Moq allows for base members to be called by setting CallBase = true on the mocked object.

[TestClass]
public class MyClass1_Test {
    [TestMethod]
    public void MyClass1_Should_Generate_Output() {
        //Arrange
        var expected = 0;
        var mock = new Mock<MyClass1>() {
            CallBase = true //<-- let mock call base members
        };
        mock.Setup(_ => _.GetValue()).Returns(expected); // <-- mocked behavior

        var sut = mock.Object; //<-- subject under test.

        //Act
        var actual = sut.GenerateOutPut();

        //Assert
        actual.Should().Be(expected + 1);
    }
}

这几乎与您手动完成的操作类似,但现在通过模拟代理完成了.

Which is almost like what you did manually but now via the mock proxy.

这篇关于C#模拟返回基本方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆