0

他のアプリケーションから呼び出すと完全に動作する残りの Web サービスがありますが、Junit テスターから呼び出すと失敗します。私は過去数時間で多くのことを読みましたが、正しく理解している場合、件名のエラーは2つの考えられる理由で発生しています.1-MockMvcを使用するとJNDIが無視され、2-クラスパスに必要なjarがありません. jar については、他のアプリケーションから呼び出されたときに正しく実行されるため、原因ではないと思います。jndi については、Web サービスが他のアプリケーションから呼び出されたときにコンテナーがデータソースを提供できるのに、モック テスターから呼び出されたときに失敗する理由がよくわかりません。それについて私が見つけた最も近い質問は、モックされた JNDI データソースを Spring でテストする方法です。. このスレッドでは、最後のコメントで良い解決策が得られたようですが、主に「jee:jndi-lookup」を使用した jndi ファイル定義がないため、実装できませんでした。簡単に言うと、残りの Web サービスはメソッドを公開するコントローラーであり、このメソッド内には接続を取得する場所があります。コントローラーを超えるものはすべて、変更することはできません。MockMvc を使用してこの残りの Web サービスをテストするにはどうすればよいですか? レスト サービスがモック テスターから呼び出されたときにロックアップが機能しないのはなぜですか? 「ic.lookup("java:comp/env/jdbc/MHE")」を実行するために、test-mvc-dispatcher-servlet.xml に構成を追加する方法はありますか?

//接続はこのメソッドから提供され、変更できません

public Connection getConnection()throws Exception{
              try{
                     InitialContext ic = new InitialContext();
                     DataSource ds = (DataSource) ic.lookup("java:comp/env/jdbc/MHE"); //the error happens here

// Web サービスを休止

@Controller
@RequestMapping("/log")
public class Lo_Controller {
       @Autowired
       private Mhe_Handler mhe_Handler; //now Autowired 

       @Autowired
       private Lo_Mas60010 lo_Mas60010;

       @Autowired
       private LogDisplay testReturn;

       @ExceptionHandler(Exception.class)
       @ResponseStatus(value=HttpStatus.NOT_FOUND,reason="Contact not found")
       public void notFound() {


              System.out.println("error ...");
       }

       @RequestMapping(value="display/last", method=RequestMethod.POST)
       @ResponseBody
       @ResponseStatus(HttpStatus.OK)
       public LogDisplay getFirst(@RequestBody Mas60010 mas60010) {

              Connection con; // it is the only object not Autowired inside the Controler but take a note that the error happens inside mhe_Handler.getConnection()
              try {
                     con = mhe_Handler.getConnection(); 

//MockMvc

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration("classpath:/com/myCompany/mhe/test/test-mvc-dispatcher-servlet.xml")
public class RestErrorHandlingTest {


    @Autowired
    private WebApplicationContext wac;

    @Autowired
    private LogDisplay logDisplay;

       @Autowired
       private Mas60010 _mas60010;

    private MockMvc mockMvc;

    @Before
    public void setup() {
        this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();

     }

    @Test
    public void postLog() throws Exception {

       Mas60010 _mas60010 = new Mas60010(
                      ... the parameters here, not relevant information
                           );

       ObjectMapper mapper = new ObjectMapper();

       this.mockMvc.perform(
                     post("/log/display/last")
                     .contentType(
                                  new MediaType(
                                                MediaType.APPLICATION_JSON.getType(),
                                                MediaType.APPLICATION_JSON.getSubtype(),
                                                Charset.forName("utf8")
                                                )
                                  )
                     .content(mapper.writeValueAsBytes(_mas60010))
                     )
                     .andExpect(status().isBadRequest())
                           .andExpect(status().isOk())
                           .andExpect(content().contentType("application/json"))
                           .andExpect(model().attribute("logDisplay", logDisplay));

//test-mvc-dispatcher-servlet.xml

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans    
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd">

       <context:annotation-config />
       <mvc:annotation-driven />
       <context:component-scan base-package="com.myCompany.mhe.common.controller, com.myCompany.mhe.log.handler, com.myCompany.mhe.utilities, com.myCompany.mhe.log.domain" />
       <context:property-placeholder location="classpath:restServices.properties"/>


       <mvc:resources mapping="/**" location="/" />

       <bean
              class="org.springframework.web.servlet.view.InternalResourceViewResolver">
              <property name="prefix">
                     <value>/WEB-INF/pages/</value>
              </property>
              <property name="suffix">
                     <value>.jsp</value>
              </property>
       </bean>


    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
        <property name="messageConverters">
            <list>
                <ref bean="jsonMessageConverter"/>
            </list>
        </property>
    </bean>


    <bean id="jsonMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
    </bean>


</beans>

//エラーログ

Dec 23, 2014 8:19:29 AM org.springframework.test.context.support.AbstractTestContextBootstrapper getDefaultTestExecutionListenerClassNames
INFO: Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener]
Dec 23, 2014 8:19:29 AM org.springframework.test.context.support.AbstractTestContextBootstrapper instantiateListeners
INFO: Could not instantiate TestExecutionListener [org.springframework.test.context.transaction.TransactionalTestExecutionListener]. Specify custom listener classes or make the default listener classes (and their required dependencies) available. Offending class: [org/springframework/transaction/interceptor/TransactionAttributeSource]
Dec 23, 2014 8:19:29 AM org.springframework.test.context.support.AbstractTestContextBootstrapper instantiateListeners
INFO: Could not instantiate TestExecutionListener [org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener]. Specify custom listener classes or make the default listener classes (and their required dependencies) available. Offending class: [org/springframework/transaction/interceptor/TransactionAttribute]
Dec 23, 2014 8:19:29 AM org.springframework.test.context.support.AbstractTestContextBootstrapper getTestExecutionListeners
INFO: Using TestExecutionListeners: [org.springframework.test.context.web.ServletTestExecutionListener@4a738d08, org.springframework.test.context.support.DependencyInjectionTestExecutionListener@68302e67, org.springframework.test.context.support.DirtiesContextTestExecutionListener@3336a1a1]
Dec 23, 2014 8:19:30 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [com/myCompany/mhe/test/test-mvc-dispatcher-servlet.xml]
Dec 23, 2014 8:19:31 AM org.springframework.beans.factory.support.DefaultListableBeanFactory registerBeanDefinition
INFO: Overriding bean definition for bean 'logDisplay': replacing [Generic bean: class [com.myCompany.mhe.log.domain.LogDisplay]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [C:\STS\wsRestTemplate\MHE_original\WebContent\WEB-INF\classes\com\myCompany\mhe\log\domain\LogDisplay.class]] with [Generic bean: class [com.myCompany.mhe.log.domain.LogDisplay]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in class path resource [com/myCompany/mhe/test/test-mvc-dispatcher-servlet.xml]]
Dec 23, 2014 8:19:31 AM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.web.context.support.GenericWebApplicationContext@68a53de4: startup date [Tue Dec 23 08:19:31 CST 2014]; root of context hierarchy
Dec 23, 2014 8:19:32 AM org.springframework.core.io.support.PropertiesLoaderSupport loadProperties
INFO: Loading properties file from class path resource [restServices.properties]
Dec 23, 2014 8:19:32 AM org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor <init>
INFO: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
Dec 23, 2014 8:19:32 AM org.springframework.web.servlet.handler.AbstractHandlerMethodMapping registerHandlerMethod
INFO: Mapped "{[/log/display/last],methods=[POST],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public com.myCompany.mhe.log.domain.LogDisplay com.myCompany.mhe.common.controller.Lo_Controller.getFirst(com.myCompany.mhe.log.domain.Mas60010)
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Dec 23, 2014 8:19:33 AM org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter initControllerAdviceCache
INFO: Looking for @ControllerAdvice: org.springframework.web.context.support.GenericWebApplicationContext@68a53de4: startup date [Tue Dec 23 08:19:31 CST 2014]; root of context hierarchy
Dec 23, 2014 8:19:33 AM org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter initControllerAdviceCache
INFO: Looking for @ControllerAdvice: org.springframework.web.context.support.GenericWebApplicationContext@68a53de4: startup date [Tue Dec 23 08:19:31 CST 2014]; root of context hierarchy
Dec 23, 2014 8:19:33 AM org.springframework.web.servlet.handler.AbstractUrlHandlerMapping registerHandler
INFO: Mapped URL path [/**] onto handler 'org.springframework.web.servlet.resource.ResourceHttpRequestHandler#0'
Dec 23, 2014 8:19:33 AM org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter initControllerAdviceCache
INFO: Looking for @ControllerAdvice: org.springframework.web.context.support.GenericWebApplicationContext@68a53de4: startup date [Tue Dec 23 08:19:31 CST 2014]; root of context hierarchy
Dec 23, 2014 8:19:58 AM org.springframework.mock.web.MockServletContext log
INFO: Initializing Spring FrameworkServlet ''
Dec 23, 2014 8:19:58 AM org.springframework.web.servlet.FrameworkServlet initServletBean
INFO: FrameworkServlet '': initialization started
Dec 23, 2014 8:19:58 AM org.springframework.web.servlet.FrameworkServlet initServletBean
INFO: FrameworkServlet '': initialization completed in 183 ms
javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file:  java.naming.factory.initial
       at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:645)
       at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:288)
       at javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:325)
       at javax.naming.InitialContext.lookup(InitialContext.java:392)
       at com.myCompany.mhe.Mhe_Handler.getConnection(Mhe_Handler.java:40)
       at com.myCompany.mhe.common.controller.Lo_Controller.getFirst(Lo_Controller.java:59)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       at java.lang.reflect.Method.invoke(Method.java:597)
       at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
       at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
       at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
       at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:781)
       at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:721)
       at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
       at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943)
       at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
       at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
       at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:868)
       at javax.servlet.http.HttpServlet.service(HttpServlet.java:595)
       at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
       at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:65)
       at javax.servlet.http.HttpServlet.service(HttpServlet.java:668)
       at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.java:167)
       at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134)
       at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:144)
       at com.myCompany.mhe.test.RestErrorHandlingTest.postLog(RestErrorHandlingTest.java:151)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       at java.lang.reflect.Method.invoke(Method.java:597)
       at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
       at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
       at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
       at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
       at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
       at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:73)
       at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)
       at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:73)
       at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
       at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:217)
       at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:83)
       at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
       at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
       at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
       at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
       at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
       at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
       at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:68)
       at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
       at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:163)
       at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
       at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
       at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
       at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
       at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
       at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
4

1 に答える 1

0

コントローラーはテスト可能に設計されていません。依存関係Mhe_Handlerは method のローカル変数としてインスタンス化されるgetFirstため、単体テストでモックアウトする方法はありません。1 つの解決策は、それをプライベート フィールドとして抽出し、自動配線することです。これは、依存性注入の最も重要な利点の 1 つです。

class Controller {

    //inject real Mhe_Handler backed by jndi datasource in production
    //while inject mockups in unit test
    @Autowired private Mhe_Handler mhe_Handler;

    public LogDisplay getFirst() { 
        //inject dependency instead of hard-wire it
        mhe_Handler.getConnection()

    }

}
于 2014-12-23T01:52:10.350 に答える