如何模拟棱镜IContainerRegistry

时间:2018-10-18 16:04:17

标签: wpf ninject prism prism-7

  • Prism.Ninject 7.1.0.431
  • Prism 7.1.0.431
  • NUnit 3.3.3
  • NSubstitute

以前使用Prism 6.3,我们进行了一组单元测试,以确认我们所有的绑定都如下所示

protected IKernel TestKernel;

[SetUp]
public void Given
{
    TestKernel = new StandardKernel();
    SUT = new MyModule( TestKernel );

    Core = Assembly.Load( "MyDLL.Core" ).GetTypes();
    Common = Assembly.Load( "MyDLL.Common" ).GetTypes();

    SUT.Initialize();
}

[ Test ]
public void Then_ViewModels_Will_Be_Bound()
{
    var testCollection = Common
        .Where( item => item.IsPublic )
        .Where( item => item.Name.EndsWith( "ViewModel" ) );

    foreach ( var item in testCollection )
    {
        Assert.That( TestKernel.GetBindings( item ).Any, $"Test Failed:  {item.Name}" );
    }
}

但是,在Ninject 7.1中,IModule接口有所更改,因此现在部件的注册方式有所不同

public void RegisterTypes(
        IContainerRegistry containerRegistry )

我只是尝试使用这种新的IModule格式启动单元测试并再次运行。我曾尝试将给定条件更改为如下

protected override void Given()
{
    TestKernel = new StandardKernel();

    TestContainerRegistry = Substitute.For<IContainerRegistry>();
    TestContainerRegistry.GetContainer().Returns( TestKernel );

    SUT = new MyModule();
}

但是,当我尝试运行测试时,得到以下提示。

System.InvalidCastException:无法将类型为“ Castle.Proxies.IContainerRegistryProxy”的对象转换为类型为“ Prism.Ioc.IContainerExtension`1 [Ninject.IKernel]”。

如果有人对我可能如何嘲笑这一点有所了解,将不胜感激,因为我目前处于僵局。

2 个答案:

答案 0 :(得分:1)

如何测试始终是一个充满争议的热门话题,因此,我将在此处尝试向您提供一些常规信息。 Prism.Ninject使用Prism.Ninject.Ioc.NinjectContainerExtension实现容器抽象。它有两个构造函数,一个是默认构造函数,一个是允许您传入特定内核的构造函数。

Prism还为每个容器实现扩展方法,以从抽象中拉出容器。您可以通过以下两种方法来实现:

containerRegistry.GetContainer().SomeContainerSpecificApi()

或者,您可以执行以下操作:

var app = new MyApp();
app.Container.GetContainer().SomeContainerSpecificApi();

同样,您可以通过多种方式实施测试,而我也不会讨论如何进行测试。但是,我要说的是,如果您不想创建应用程序,而只是想验证自己的类型已注册为棱镜模块,则可以尝试以下操作:

var containerExtension = new NinjectContainerExtension();
var module = new MyModule();
module.RegisterTypes(containerExtension);
Assert.IsTrue(containerExtension.Instance.IsRegistered<MyType>());

答案 1 :(得分:0)

我想我已经解决了(或者至少取得了进展)

我不得不使用以下内容来代替IContainerRegistry

<?xml version="1.0" encoding="UTF-8" ?>

<web-app    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns="http://java.sun.com/xml/ns/javaee"
            xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
            version="3.0">

    <!-- DEFINE APPLICATION ENVIRONMENT  -->
    <context-param>
        <param-name>javax.faces.PROJECT_STAGE</param-name>
        <param-value>Development</param-value>
    </context-param>

    <!-- DEFINE JSF SERVLET MAPPING   -->
    <servlet>
        <servlet-name>FACES SERVLET</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>FACES SERVLET</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>

    <!-- DEFINE WELCOME PAGE -->
    <welcome-file-list>
        <welcome-file>index.xhtml</welcome-file>
    </welcome-file-list>

    <!--    SPRING SERVLETS -->

    <servlet>
        <servlet-name>dispatcher-servlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:/conf/applicationContext.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher-servlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!--    SPRING CONTEXT -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:conf/applicationContext.xml</param-value>
    </context-param>


    <!--        SPRING SECURITY FILTER -->
    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
        <!-- Add this dispatcher to handle /j_spring_security_check url -->
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
    </filter-mapping>

</web-app>

尽管为了使containerRegistry.Register(等)出现在我的TestKernel中进行验证,看来我将不得不做更多替代工作。