[英]Mock objects being created inside a method while Unit Testing
我有以下情况:
public void DoSomething(...)
{
...
ClassA obj1 = new ClassA();
ClassB obj2 = new ClassB();
ClassC obj3 = new ClassC();
...
}
我了解,如果我使用依赖倒置原则,则可以模拟该接口,它将起作用。 问题在于仅在此方法中才需要这些实例,因此在类级别创建它们是没有意义的。 最重要的是,某些方法具有5-6个对象声明,因此将这些参数作为参数传递将使参数列表膨胀。
无论如何,我可以使用Moq,NMock等来模拟这些类(基于通用接口)吗?
如果只需要在该方法中实例化这些类型, 那是对的,因为它们不应被注入类中。
相反,典型的解决方案是注入一个工厂,该工厂将允许您的方法解析接口。
这是通常的方法:
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允许您注入基于委托的工厂 ,而不是上面基于接口的工厂:
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());
您可以使用诸如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
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.