有没有办法使用Moq自动模仿真实世界构造函数的属性?

时间:2015-06-18 11:15:46

标签: c# asp.net-mvc asp.net-web-api moq

我有一个带有大量构造函数注入的控制器:

public MoviesController(ISession session, IClientContext clientContext, PManager pManager, ISegmentationService segmentationService, IGeoLocator geoLocator, IBus bus)
{
    _session = session;
    _clientContext = clientContext;
    _pManager = pManager;
    _segmentationService = segmentationService;
    _geoLocator = geoLocator;
    _bus = bus;
}

根据我的理解(只读了Mocking),如果我希望基于这个控制器制作一个全面的测试套件,我可以手动设置很多Mock对象属性。

对于一种方法,我只使用一种服务(我甚至希望尽可能少地自动化):

public object Show(Guid id)
{
    var movie = _session.Get<movie>(id);
    return movie;
}

但是在另一个中使用了很多服务 - 有没有办法快速设置这些Moq对象?我真的可以使用一些例子,因为我不熟悉测试。这是一个捆绑了webapi 1的asp.net mvc项目(在这里测试webapi控制器)

2 个答案:

答案 0 :(得分:0)

对于您的示例,您只需要模拟会话,并且可以将所有其他依赖项保留为null,因为它们的行为应与您正在测试的行为无关:

Mock<ISession> mockSession = new Mock<ISesssion>();
MoviesController controller = new MoviesController(mockSession.Object, null,null,null,null,null);

除了您为此特定测试所需的模拟之外,您无需设置任何模拟

答案 1 :(得分:0)

正如在评论中所说,如果你有通用的设置代码,你可以把它放在一个安装方法中,在每次测试之前从你的测试框架自动调用。如果您使用MStest,如果您正在使用Nunit Setup,则会使用TestInitialize属性进行修饰。如果您正在使用XUnit,请it's a bit different

所以,你的课可能看起来像这样:

public class SomeTests {
    Mock<ISession> _sessionMock;
    Mock<IClientContext> _clientContextMock;

    [Setup]
    public void Setup() {
        _sessionMock = new Mock<ISession>();
        _clientContextMock = new Mock <IClientContext();
    }

    MovieController CreateSut() {
        return new MovieController(_sessionMock.Object, _clientContextMock.Object, ...);
    }

    [Test]
    public void TestSomething() {
        _sessionMock.Setup(x=>...);

        //...

        var sut = CreateSut();

       //...
    }
}  

如果您尝试远离手动完全创建模拟,那么您可能希望查看AutoFixture with AutoMoq之类的内容。在创建接受接口的对象时,这将自动提供模拟实例。 AutoFixture非常有用,但有效使用它有一个学习曲线,因此您可能需要查看教程/快速入门。

你也可以配置一个IOC容器来为你的测试项目提供模拟实例,尽管我自己从来没有走过这条路线。