c# mock return base method

点点圈 提交于 2020-01-06 07:14:31

问题


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();
    }
}

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

I was trying to

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

but it doesn't allow.

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 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;
    }
}

i made a class for testing MyClass1 like below:

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

test case as below:

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

    assert.AreEqual(101, result);
}

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?


回答1:


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.

Using MyClass1 from your example

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

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.



来源:https://stackoverflow.com/questions/48057304/c-sharp-mock-return-base-method

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!