我有一个场景:
public void DoSomething(...)
{
...
ClassA obj1 = new ClassA();
ClassB obj2 = new ClassB();
ClassC obj3 = new ClassC();
...
}我知道,如果我使用依赖反转原则,我可以模拟接口,它将工作。问题是这些实例只在这个方法中需要,所以在类级别创建它们没有意义。最重要的是,一些方法有5-6个对象声明,因此将这些作为参数传递会使参数列表变得臃肿。
有没有什么办法我可以使用Moq,NMock等来模拟这些类(它们基于一个公共接口)?
发布于 2014-07-24 07:07:46
如果只需要在该方法中实例化这些类型,那么就不应该将它们注入到类中,这一点是正确的。
相反,典型的解决方案是注入一个工厂,它将允许您的方法解析接口。
下面是常用的方法:
interface IMessageFactory
{
IMessage CreateMessage(string text);
}
class ConcreteMessageFactory : IMessageFactory
{
IMessage CreateMessage(string text) { return new Message(text); }
}
class MockMessageFactory : IMessageFactory
{
public IMessage CreateMessage(string text) { return new MockMessage(text); }
}
class MyClient
{
private readonly IMessageFactory _msgFactory;
public MyClient(IMessageFactory msgFactory)
{
_msgFactory = msgFactory;
}
public void SendMessage(string text)
{
IMessage msg = _msgFactory.CreateMessage(text);
msg.Send();
}
}
//Usage:
new MyClient(new ConcreteMessageFactory());
//Mocking
new MyClient(new MockMessageFactory());根据您正在使用的DI框架,该框架可以让您更轻松地实现这一点。例如,Castle Windsor允许您注入delegate-based factory,而不是上面基于接口的工厂:
class MyClient
{
private readonly Func<string, IMessage> _msgFactory;
public MyClient(Func<string, IMessage> msgFactory)
{
_msgFactory = msgFactory;
}
public void SendMessage(string text)
{
IMessage msg = _msgFactory(text);
msg.Send();
}
}
//Usage:
new MyClient(() => new Message());
//Mocking
new MyClient(() => new MockMessage());发布于 2014-07-24 07:02:35
你可以使用像StructureMap这样的东西来为你做这项工作,你的方法就会变成这样。
public void DoSomething(...)
{
...
IClassA obj1 = ObjectFactory.GetInstance<IClassA>();
IClassB obj2 = ObjectFactory.GetInstance<IClassB>();
IClassC obj3 = ObjectFactory.GetInstance<IClassC>();
...
}然后通常你会像这样在global.asax或类似的地方映射它们
ObjectFactory.Initialize(x =>
{
x.ForRequestedType<IClassA>().TheDefaultIsConcreteType<ClassA>();
...etc
});但是对于你的单元测试
ObjectFactory.Initialize(x =>
{
x.ForRequestedType<IClassA>().TheDefaultIsConcreteType<UnitTestClassA>();
...etc
});https://stackoverflow.com/questions/24922416
复制相似问题