2009-05-14 18 views
18

、あなたは、特定のURLが特定の方法で処理されることを指定でき、その特定のパラメータがそうのように、特定の引数にマップされます指定することができます。テストSpring MVCの注釈mapppings

@Controller 
public class ImageController { 

    @RequestMapping("/getImage") 
    public String getImage(@RequestParam("imageId") int imageId, Map<String,Object> model) { 
     model.put("image",ImageService.getImage(imageId)); 
    } 

} 

このすべてうまくいきましたが、imageIdパラメータを指定したhttpリクエストでこのメソッドが正しく呼び出されることをテストします。言い換えれば、注釈を削除したり変更したりすると、テストが壊れてしまいます。これを行う方法はありますか?

getImageが正しく動作することをテストするのは簡単です。 ImageControllerを作成し、適切な引数を指定してgetImageを呼び出すことができます。しかし、これはテストの半分に過ぎません。テストの残りの半分は、適切なHTTPリクエストが来たときにgetImage()がSpringフレームワークによって呼び出されるかどうかでなければなりません。特に、私の@RequestMappingの注釈がより複雑になり、パラメータ条件。

私が4行目を削除した場合に破損するテストを表示できますか?@RequestMapping("getImage")

+1

私はあなたの質問を完全に理解していません。 「アノテーションマッピングを使用するSpring MVCコントローラのユニットテストの作成方法」を意味しますか? –

+0

申し訳ありません。私は注釈が正しいこと、そしてHTTPリクエストが実際にこのメソッドを呼び出すことをテストしたいということです。 –

答えて

12

AnnotationMethodHandlerAdapterとそのhandleメソッドをプログラムで使用できます。これにより、指定されたリクエストのメソッドが解決され、実行されます。残念ながら、これは少し間接的です。実際には、AMHAにServletHandlerMethodResolverと呼ばれるプライベートクラスがあり、それは与えられたリクエストのメソッドをただ解決する責任があります。私はちょうどそのトピックにrequest for improvementを提出しました。私は本当にこれもまた見たいと思っています。

EasyMockあなたのコントローラクラスのモックを作成するには、与えられたメソッドが呼び出され、そのモックをhandleに渡すことを期待してください。

コントローラー:

@Controller 
public class MyController { 

    @RequestMapping("/users") 
    public void foo(HttpServletResponse response) { 

    // your controller code 
    } 
} 

テスト:

public class RequestMappingTest { 

    private MockHttpServletRequest request; 
    private MockHttpServletResponse response; 
    private MyController controller; 
    private AnnotationMethodHandlerAdapter adapter; 


    @Before 
    public void setUp() { 

    controller = EasyMock.createNiceMock(MyController.class); 

    adapter = new AnnotationMethodHandlerAdapter(); 
    request = new MockHttpServletRequest(); 
    response = new MockHttpServletResponse(); 
    } 


    @Test 
    public void testname() throws Exception { 

    request.setRequestURI("/users"); 

    controller.foo(response); 
    EasyMock.expectLastCall().once(); 
    EasyMock.replay(controller); 

    adapter.handle(request, response, controller); 

    EasyMock.verify(controller); 
    } 
} 

よろしく、 Ollie第

+0

余分な行を追加する: 'request.setAttribute(HandlerMapping.INTROSPECT_TYPE_LEVEL_MAPPING、Boolean.TRUE);'コントローラレベルのマッピングを使用する場合に必要です – takacsot

6

Ollie第のソリューションをテストする方法のより広い問題について、具体的な注釈の例が、何のテストをカバー他のすべてのSpring MVCアノテーション(簡単に他の注釈に拡張することができます)私のアプローチは、私もblog entry about integration testing Spring MVC annotationsを書いた

import static org.springframework.test.web.ModelAndViewAssert.*; 

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration({/* include live config here 
    e.g. "file:web/WEB-INF/application-context.xml", 
    "file:web/WEB-INF/dispatcher-servlet.xml" */}) 
public class MyControllerIntegrationTest { 

    @Inject 
    private ApplicationContext applicationContext; 

    private MockHttpServletRequest request; 
    private MockHttpServletResponse response; 
    private HandlerAdapter handlerAdapter; 
    private MyController controller; 

    @Before 
    public void setUp() { 
     request = new MockHttpServletRequest(); 
     response = new MockHttpServletResponse(); 
     handlerAdapter = applicationContext.getBean(HandlerAdapter.class); 
     // I could get the controller from the context here 
     controller = new MyController(); 
    } 

    @Test 
    public void testFoo() throws Exception { 
     request.setRequestURI("/users"); 
     final ModelAndView mav = handlerAdapter.handle(request, response, 
      controller); 
     assertViewName(mav, null); 
     assertAndReturnModelAttributeOfType(mav, "image", Image.class); 
    } 
} 

だろう。

関連する問題