有什么方法可以使用 Moq 自动模仿真实世界构造函数的属性?
Any way to use Moq to imitate properties of a real-world constructor automatically?
我有一个带有大量构造函数注入的控制器:
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 对象吗?我真的可以使用一些示例,因为我是测试新手。这是一个 asp.net 捆绑了 webapi 1 的 mvc 项目(在此处测试 webapi 控制器)
对于您的示例,您只需要模拟会话,并且可以将所有其他依赖项留空,因为它们的行为应该与您正在测试的行为无关:
Mock<ISession> mockSession = new Mock<ISesssion>();
MoviesController controller = new MoviesController(mockSession.Object, null,null,null,null,null);
除了此特定测试所需的模拟之外,您无需设置任何模拟
正如评论中所说,如果您有通用的设置代码,您可以将它放在一个设置方法中,该方法在每次测试之前从您的测试框架自动调用。如果您使用 Nunit TestInitialize
如果您使用 MStest,它会用 Setup
属性装饰。如果您使用的是 XUnit,那么 it's a bit different.
因此,您的 class 可能如下所示:
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 容器来为你的测试项目提供模拟实例,尽管我自己从来没有走那条路。
我有一个带有大量构造函数注入的控制器:
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 对象吗?我真的可以使用一些示例,因为我是测试新手。这是一个 asp.net 捆绑了 webapi 1 的 mvc 项目(在此处测试 webapi 控制器)
对于您的示例,您只需要模拟会话,并且可以将所有其他依赖项留空,因为它们的行为应该与您正在测试的行为无关:
Mock<ISession> mockSession = new Mock<ISesssion>();
MoviesController controller = new MoviesController(mockSession.Object, null,null,null,null,null);
除了此特定测试所需的模拟之外,您无需设置任何模拟
正如评论中所说,如果您有通用的设置代码,您可以将它放在一个设置方法中,该方法在每次测试之前从您的测试框架自动调用。如果您使用 Nunit TestInitialize
如果您使用 MStest,它会用 Setup
属性装饰。如果您使用的是 XUnit,那么 it's a bit different.
因此,您的 class 可能如下所示:
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 容器来为你的测试项目提供模拟实例,尽管我自己从来没有走那条路。