2017-02-07 12 views
3

JUnit、Mockito & spring-testを使用してSpring MVCコントローラをテストしています。残念ながら、テストではコントローラメソッドの@PreAuthorizeアノテーションが無視されており、解決できませんでした。キーコードスニペットは以下の通りですが、私はMyControllerの依存関係からの応答を嘲笑して短くしておくための無関係なロジックを削除しました。私はSpring 3.2 & JUnit 4を使用しています.Maven経由で直接Eclipse(Run as - > JUnit test)でテストを実行しています。私は、任意のauthおよび/事前認証アノテーションを付けている上にルートマップを占め方法、しかし、メソッドが呼び出されているを提供していないようSpringコントローラのPreAuthorizeアノテーションはテスト時に無視されます

は、今私は、 getAccounts_ReturnsOkStatusテストが失敗することを期待しています事前認証チェックはバイパスされます。

MyControllerTest.java

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = { "classpath:applicationContext-test.xml" }) 
public class MyControllerTest { 

    private MockMvc mockMvc; 

    @Mock 
    private MyService myService; 

    @InjectMocks 
    private MyController myController; 

    @Before 
    public void init() { 
     MockitoAnnotations.initMocks(this); 
     mockMvc = MockMvcBuilders.standaloneSetup(myController).build(); 
    } 

    @Test 
    public void getAccounts_ReturnsOkStatus() throws Exception { 
     // Make the GET request, and verify that it returns HttpStatus.OK (200) 
     mockMvc.perform(MockMvcRequestBuilders.get("/accounts")) 
       .andExpect(MockMvcResultMatchers.status().isOk()); 
    } 
} 

のApplicationContext-のtest.xml

<sec:global-method-security pre-post-annotations="enabled" /> 
<bean id="applicationContextProvider" class="com.myapp.springsupport.ApplicationContextProvider" /> 

<sec:authentication-manager alias="authenticationManager"> 
    <sec:authentication-provider> 
     <sec:user-service> 
      <sec:user name="test-superuser" password="test-pwd" authorities="ROLE_SUPERUSER" /> 
     </sec:user-service> 
    </sec:authentication-provider> 
</sec:authentication-manager> 

MyController.java

@PreAuthorize("isAuthenticated() and hasRole('ROLE_SUPERUSER')") 
@RequestMapping(value = "/accounts", method = RequestMethod.GET) 
@ResponseBody 
public Collection<Account> getAccounts() { 
    return new ArrayList<Account>(); 
} 

ApplicationContextのテストアプリケーションコンテキストは間違い手動

Authentication auth = new UsernamePasswordAuthenticationToken(name, password); 
SecurityContextHolder.getContext().setAuthentication(am.authenticate(auth)); 

のみ(他の認証プロバイダの非存在下で)試験の設定で指定されたユーザ認証情報と動作を使用して認証するため、使用されています。さらに、SELを使用してメソッド&をデバッグしてテストしたので、事前認証が無視されていることを確認できます。

私には何が欠けていますか?

答えて

2

mockMvcをビルドするときは、テスト用のスプリングセキュリティを有効にする必要があります。春4では

それはこのようなものだ:春3では

mockMvc = MockMvcBuilders.webAppContextSetup(context) 
         .apply(springSecurity()) 
         .build(); 

それはこのようなものだ:詳細については

@Autowired 
private Filter springSecurityFilterChain; 
... 
mockMvc = MockMvcBuilders.webAppContextSetup(context) 
         .addFilters(springSecurityFilterChain) 
         .build(); 

は、以下を参照してください。

+0

ありがとうございます。私が今直面している主な問題は、 'standaloneSetup'ではなく 'webAppContextSetup'を使用するとコンポーネントスキャンを使用してapplicationContextにコントローラを含める必要があることです。しかし、これを行うには、コントローラにオートワイヤードされたすべてのクラスも含めてください。すべてがテストで嘲笑され、実装自体は使用されていません。私の設定には明らかに何か間違いがありますが、私は何を解決することはできません。 – DGoodman

+1

http://docs.spring.io/spring-security/site/docs/current/reference/html/test-mockmvc.html#test-mockmvc-securitycontextholder-rppをご覧ください。 'standaloneSetup'をどのように使用することができるかを説明しています。'webAppContextSetup'を使うときは、' @MockBean'(http://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/test/mock/mockito/MockBean.html)を見てください。これを使用して、コントローラ内のautowired beanをモックすることができます。 –

関連する問題