我有以下情况:

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允许您注入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());

关于c# - 单元测试时在方法内部模拟对象,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24922416/

10-13 07:46
查看更多