无法解析Unity的界面

时间:2014-02-06 20:37:34

标签: c# unit-testing interface mocking unity-container

问题背景:

我使用unity来解析一个类及其所有依赖项。

问题:

我想通过Unity传递接口类型的类的构造函数,我试图按如下方式实现:

public static IFacade UnityNewsFacadeResolver()
   {
           IUnityContainer unityContainer = new UnityContainer();
           unityContainer.RegisterType<IFacade, NewsFacade>();
           IFacade newsFacadeInstance = unityContainer.Resolve<NewsFacade>();

           return newsFacadeInstance;
   }

以下显示Unity设置构造函数参数的'NewsFacade'类。注意它是传递一个'NewsStoryHandler'的具体类型,我想传入这个类所基于的接口,即INewsStoryHandler:

private INewsStoryHandler _NewsStoryHandler;

    //*****Unity will only pass in a concrete implementation, I want to pass it as an interface but cannot:******
    public NewsFacade(NewsStoryHandler newsStoryHandler)
    {
        if (newsStoryHandler == null)
        {
            throw new Exception("newsStoryHandler is null at the constrcutor");
        }

        _NewsStoryHandler = newsStoryHandler;
    }

目前Unity不会解析并传入接口类型,它必须是如上所示的具体实现。这意味着我在单元测试时无法模拟界面。

有人可以告诉我为什么Unity不会根据其界面解析和传递类型吗?

1 个答案:

答案 0 :(得分:2)

Unity完全有能力根据其界面解析和提供类型。

为此,您必须确保团结知道要提供的具体实施,即

// Instruct unity to inject a NewsStoryHandler everywhere an INewsStoryHandler is specified
unityContainer.RegisterType<INewsStoryHandler, NewsStoryHandler>();
var newsFacadeInstance = unityContainer.Resolve<NewsFacade>();

这可以假设您已将NewsFacade构造函数更改为具有INewsStoryHandler类型的参数。

在单元测试方面,您可以模拟INewsStoryHandler来测试您的NewsFacade更简单,一个使用Moq的例子:

// Setup and configure the mock
var mockNewsStoryHandler = new Mock<INewsStoryHandler>();
mockNewsStoryHandler.Setup(h => h.GetAllStories()).Returns(Enumerable.Empty<NewsStory>());

// Inject the mock
var newsFacade = new NewsFacade(mockNewsStoryHandler.Object);
newsFacade.DoSomethingWithAllStories();

// Verify GetAllStories() was called exactly once
mockNewsStoryHandler.Verify(h => h.GetAllStories(), Times.Once);