C# 4.0 如何模拟类的单个方法?
我不熟悉使用模拟框架来模拟对象进行单元测试。我目前正在使用Rhino Mock,我想它会有一个方法来做我没有找到的事情。下面是一个LinqPad程序(只需将其复制并粘贴到C#program查询中,它就会正常工作),它显示了我正在尝试做的事情:C# 4.0 如何模拟类的单个方法?,c#-4.0,rhino-mocks,C# 4.0,Rhino Mocks,我不熟悉使用模拟框架来模拟对象进行单元测试。我目前正在使用Rhino Mock,我想它会有一个方法来做我没有找到的事情。下面是一个LinqPad程序(只需将其复制并粘贴到C#program查询中,它就会正常工作),它显示了我正在尝试做的事情: public interface MyTest{ int A(int i); string B(int i); } /// This is an actual class that is a black box to me. public
public interface MyTest{
int A(int i);
string B(int i);
}
/// This is an actual class that is a black box to me.
public class ActualClass : MyTest {
public int A(int i){
// Does some work
return ++i;
}
public string B(int i){
return A(i).ToString();
}
}
/// I'd like to create a mocked class that uses an instance of the actual class
/// to provide all of the implementations for the interface except for a single method
/// where I can check the parameter values, and provide my own return value,
/// or just call the actual class
public class MockedClass : MyTest {
private ActualClass _actual;
public MockedClass(ActualClass actual){
_actual = actual;
}
public int A(int i){
if(i == 1){
return 10;
}else{
return _actual.A(i);
}
}
public string B(int i){
return _actual.B(i);
}
}
void Main()
{
var mock = new MockedClass(new ActualClass());
mock.A(0).Dump();
mock.A(1).Dump();
mock.A(2).Dump();
mock.B(0).Dump();
mock.B(1).Dump();
mock.B(2).Dump();
}
结果:
1
10
3
1
2
3
我该怎么做来模拟单元测试呢。我需要某种依赖项注入程序吗?是的,您可以根据传入的参数更改模拟对象的返回值。我不会采用混合真实依赖项和模拟依赖项的方法——真实依赖项中的bug有太多机会潜入测试 下面是一个可以在MyTest接口上使用的示例,它检查模拟方法的输入参数并相应地设置返回值:
var mock = MockRepository.GenerateStub<MyTest>();
mock.Stub(m => m.A(Arg<int>.Is.Anything))
.Return(99)
.WhenCalled(mi =>
{
var arg = Convert.ToInt32(mi.Arguments[0]);
switch (arg)
{
case 0:
mi.ReturnValue = 10;
break;
case 1:
mi.ReturnValue = 20;
break;
case 2:
mi.ReturnValue = 30;
break;
default:
mi.ReturnValue = -1;
break;
}
});
var mock=MockRepository.GenerateStub();
mock.Stub(m=>m.A(Arg.Is.Anything))
.报税表(99)
.何时调用(mi=>
{
var arg=Convert.ToInt32(mi.Arguments[0]);
开关(arg)
{
案例0:
mi.ReturnValue=10;
打破
案例1:
mi.ReturnValue=20;
打破
案例2:
mi.ReturnValue=30;
打破
违约:
mi.ReturnValue=-1;
打破
}
});
请注意,之所以需要“Return(99)”,是因为在存根一个返回值的方法时,Rhino.Mocks要求定义要抛出的异常或定义一个返回值。即使我们不使用返回值(因为我们在WhenCalled处理程序中提供了自己的返回值),它仍然必须定义或Rhino.Mocks在第一次调用存根时将引发异常。您的意思是如何使用Rhino mock创建类来替换MockedClass?@CuongLe是的。在我的实际类中有很多方法,我不想手工实现它们,即使它是锅炉板代码。为什么不试试继承的MockedClass:AactualClass?那么你不需要添加无用的方法?你实际上想测试什么?如果您试图测试
ActualClass
,那么您不需要MockedClass
(它实现了与ActualClass
相同的接口),您需要一个模拟类来测试ActualClass
@voithos的依赖关系。我正在尝试测试一些对ActualClass进行100次调用的业务逻辑。其中一个调用涉及一些active directory用户逻辑,如果bool有效,则返回bool。我不能在我们的测试环境中进行复制,所以我只想返回一个true而不是一个error。