正如标题所说,我正在尝试解决一个实现具体类的接口,该接口也需要一个构造函数。
以下是具体的服务类作为示例:
public class MessageService : IMessageService
{
private readonly IMessageGenerator _messageGenerator;
public MessageService(IMessageGenerator messageGenerator)
{
_messageGenerator = messageGenerator;
}
public string GetMessage()
{
return string.Concat(_messageGenerator.GetMessage(), "");
}
}
如您所见,此服务类还需要一个接口作为构造函数参数。 MVC控制器构造函数如下所示:
private readonly IMessageService _messageSvc;
public HomeController(IMessageService messageSvc)
{
_messageSvc = messageSvc;
}
由于Unity.Mvc3
,我已经解决了Bootstrapper中的接口问题var container = new UnityContainer();
container
.RegisterType<IMessageService, MessageService>()
.RegisterType<IMessageGenerator, MessageGenerator>();
所以我遇到的主要问题是如何使用UnityAutoMoq将IMessageGenerator接口的模拟实例传递给单元测试中的IMessageService?我认为这样的事情会起作用,但事实并非如此:
[TestMethod]
public void Index()
{
var container = new UnityAutoMoqContainer();
var controllerContext = container.Resolve<ControllerContext>();
var nMsgSvc = container.Resolve<IMessageService>(container.Resolve<IMessageGenerator>);
var sut = new HomeController(nMsgSvc) { ControllerContext = controllerContext };
ViewResult result = sut.Index() as ViewResult;
Assert.AreEqual("Hello from the MessageGenerator via the MessageService", result.ViewBag.Message);
}
答案 0 :(得分:2)
在测试控制器时,您不需要这样做。在这种情况下,控制器只需要模拟IMessageService。
此外,为了测试Index方法,我根本不会使用容器,因为它没有参与。
这样的事情应该这样做:
// arrange
var messageService = new Mock<IMessageService>();
// setup message service
...
var controller = new HomeController(messageService.Object);
// act
...
答案 1 :(得分:1)
很久以前就提出过这个问题。但我会提供一个可能有用的答案。你真的不想存根IMessageGenerator。你想要的是存根是IMessageService。并将其配置为返回所需的消息。从IMessageGenerator返回的内容并不是您的Controller的关注点。如果您在Controller中使用IMessageGenerator,那么这只会成为一个问题。
请注意,使用UnityAutoMoq容器时,您的测试也写得不好。
您可以配置IMessageService以返回所需的字符串,如下所示。
[TestMethod]
public void Index_ViewData_ContainsExpectedMessage()
{
var container = new UnityAutoMoqContainer();
var messageToReturnViaMessageGenerator = "Hello from the MessageGenerator via the MessageService";
var messageGenratorStub = container.GetMock<IMessageService>();
messageGenratorStub.Setup(x => x.GetMessage()).Returns(messageToReturnViaMessageGenerator);
var sut = container.Resolve<HomeController>();
ViewResult result = sut.Index() as ViewResult;
Assert.AreEqual(messageToReturnViaMessageGenerator, result.ViewBag.Message);
}
有几点需要注意
解决Sut ......
var sut = container.Resolve<HomeController>();
这将返回您的sut(系统测试中)。此实例还可以包含您使用UnityAutoMoqContainer存根的任何存根实例。在这种情况下,它是存根的IMessageService。这样,您就不必将存根的IMessageService实例显式传递给Controller的构造函数。
HTH