0

正如标题所说,我正在尝试解析一个实现了一个具体类的接口,该类也接受一个构造函数。

下面以具体的服务类为例:

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);
    }
4

2 回答 2

2

测试控制器时不需要这样做。在那种情况下,控制器只需要一个 IMessageService 的模拟。

此外,为了测试 Index 方法,我根本不会使用容器,因为它不涉及。

这样的事情应该这样做:

// arrange
var messageService = new Mock<IMessageService>();
// setup message service
...

var controller = new HomeController(messageService.Object);

// act
...
于 2012-10-03T02:46:50.693 回答
1

这个问题很久以前就被问过了。但我会提供一个可能有帮助的答案。您真的不想存根 IMessageGenerator。您想要删除的是 IMessageService。并将其配置为返回您想要的消息。从 IMessageGenerator 返回的内容与您的控制器无关。如果您在 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);
    }

有几点需要注意

  • 您不需要解析 ControllerContext - 出于本测试的目的,它是不必要的
  • 解决苏...

        var sut = container.Resolve<HomeController>();
    

这将返回您的 sut(被测系统)。此实例还可以包含您使用 UnityAutoMoqContainer 存根的任何存根实例。在这种情况下,它是存根的 IMessageService。这样,您不必将存根的 IMessageService 实例显式传递给 Controller 的构造函数。

  • 只是一个未成年人 - 总是给出一个可读的测试名称;)

高温高压

于 2013-08-29T11:26:56.557 回答