C#模拟返回基本方法 [英] c# mock return base method
问题描述
我正在使用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屋!