我有以下情况:
我想模拟一个界面,以便我可以对我的应用进行单元测试。我试图不创建一个实现我的接口的新mock类,但创建一个继承原始具体类的新类,并在调用该方法时使用new关键字强制新行为。但由于某种原因,正在调用具体类的方法,而不是我创建的类(作为模拟)
以下代码:
public interface IMyService
{
Model GetModelData(int id)
}
public class MyService : IMyService
{
public Model GetModelData(int id)
{
//call to db
}
}
public class MyService2 : MyService
{
public MyService2()
: base(new MyRepository())
{
}
public new Model GetModelData(int id)
{
return new Model();
}
}
注入依赖:
x.ForRequestedType<IMyService>().TheDefaultIsConcreteType<MyService2>();
检索具体类:在调试时我可以看到myService指向MyService2类,但该方法在MyService类上执行。
_myServie = ObjectFactory.GetInstance<IMyService>();
Model modelData = _myServie.GetModelData(5);
答案 0 :(得分:3)
只需使用new
即可创建新方法,而无需将其与界面相关联。您正在使用真实代码中的接口(我假设),因此您希望将接口方法绑定到新方法。为此,您必须声明您再次实施界面。以下是显示差异的示例:
using System;
interface IFoo
{
void Bar();
}
class Normal : IFoo
{
public void Bar()
{
Console.WriteLine("Normal.Bar");
}
}
class Extended1 : Normal
{
public new void Bar()
{
Console.WriteLine("Extended1.Bar");
}
}
class Extended2 : Normal, IFoo
{
public new void Bar()
{
Console.WriteLine("Extended2.Bar");
}
}
class Test
{
static void Main()
{
IFoo x = new Extended1();
IFoo y = new Extended2();
x.Bar();
y.Bar();
}
}
输出:
Normal.Bar
Extended2.Bar
因此,如果您将类声明更改为:
public class MyService2 : MyService, IMyService
你应该发现它只是有效。我不能说我是这种方法的忠实粉丝,请注意 - 调用方法的MyService
内的任何内容都会调用自己的实现,除非它恰好通过调用IMyService
- 类型参考。你可以在你的具体类虚拟中实现接口实现,而在你的子类中覆盖它;在某些方面会更好,但在其他方面会更糟。基本上,这种半继承&#34;对我来说感觉很脆弱。
我怀疑如果你有一个抽象的基类,你的真实实现和你的测试实现都来自......
答案 1 :(得分:1)
我认为您正在寻找的是将MyService上的方法设为虚拟并在MyService2中覆盖它。像这样:
public interface IMyService
{
Model GetModelData(int id)
}
public class MyService : IMyService
{
public virtual Model GetModelData(int id)
{
//call to db
}
}
public class MyService2 : MyService
{
public MyService2()
: base(new MyRepository())
{
}
public override Model GetModelData(int id)
{
return new Model();
}
}
这样,如果在子类中重写该方法,则将调用子类方法,否则基类将使用方法调用。