2015-11-04 21 views
7

Spring BootSpring securityを使用して保護されているレストコントローラをテストし、その中にモックを使用したいと思います。私はMockitoを試してみましたが、どんなモッキングツールもそのトリックを行うべきだと思います。春MockMVC、春のセキュリティとMockito

私のテストでは春のセキュリティを有効にするには、私が最初に次のように行った:

@RunWith(SpringJUnit4ClassRunner.class) 
@SpringApplicationConfiguration(classes = Main.class) 
@TestPropertySource(value="classpath:application-test.properties") 
@WebAppConfiguration 
@ContextConfiguration 
public class MyTest{ 

    protected MockMvc mockMvc; 

    @Autowired 
    private WebApplicationContext wac; 

    @Before 
    public void setUp(){ 
     mockMvc = MockMvcBuilders 
       .webAppContextSetup(wac) 
       .apply(SecurityMockMvcConfigurers.springSecurity()) 
       .build(); 
    } 

    @Test 
    public void doTheTest(){ 
     mockMvc.perform(post("/user/register") 
      .with(SecurityMockMvcRequestPostProcessors.csrf()) 
      .content(someContent())); 
    } 
} 

そこまで、それがうまく動作します。

この手順の後、私は保護されたコントローラを単独でテストするためにモックを追加したいと考えました。

@RunWith(SpringJUnit4ClassRunner.class) 
@SpringApplicationConfiguration(classes = Main.class) 
@TestPropertySource(value="classpath:application-test.properties") 
@WebAppConfiguration 
@ContextConfiguration 
public class MyTest{ 

    protected MockMvc mockMvc; 

    @Mock 
    private Myservice serviceInjectedInController; 

    @InjectMocks 
    private MyController myController; 

    @Autowired 
    private WebApplicationContext wac; 

    @Before 
    public void setUp(){ 
     mockMvc = MockMvcBuilders 
       .webAppContextSetup(wac) 
       .apply(SecurityMockMvcConfigurers.springSecurity()) 
       .build(); 
    } 

    @Test 
    public void doTheTest(){ 
     mockMvc.perform(post("/user/register") 
      .with(SecurityMockMvcRequestPostProcessors.csrf()) 
      .content(someContent())); 
    } 
} 

残念ながら、MockMVCとモックに関連するものがないと嘲笑サービスは、コントローラに注入されていないので、モックは、コントローラに注入されていません。

@RunWith(SpringJUnit4ClassRunner.class) 
@SpringApplicationConfiguration(classes = Main.class) 
@TestPropertySource(value="classpath:application-test.properties") 
@WebAppConfiguration 
@ContextConfiguration 
public class MyTest{ 

    protected MockMvc mockMvc; 

    @Mock 
    private Myservice serviceInjectedInController; 

    @InjectMocks 
    private MyController myController; 


    @Before 
    public void setUp(){ 
     mockMvc = MockMvcBuilders 
       .standAloneSetup(myController) 
       .apply(SecurityMockMvcConfigurers.springSecurity()) 
       .build(); 
    } 

    @Test 
    public void doTheTest(){ 
     mockMvc.perform(post("/user/register") 
      .with(SecurityMockMvcRequestPostProcessors.csrf()) 
      .content(someContent())); 
    } 
} 

しかし、この場合には、私は別の問題があり、次のよう

は、だから私は、MockMVCの構成を変更しようとしました。春のセキュリティは設定文句を言っている:

java.lang.IllegalStateException: springSecurityFilterChain cannot be null. Ensure a Bean with the name springSecurityFilterChain implementing Filter is present or inject the Filter to be used. 

私はセキュリティやモックを作るために、他のアイデアを持っていません。何か案が?それとも私は別のやり方をするべきですか?

ありがとうございました。

+0

あなたは春のセキュリティを使用している4+バージョンを:明示的に使用してspringSecurityFilterChainを提供することができますか? – Ritesh

+0

私はSpringブート1.2.7.RELEASEを使用しており、デフォルトのSpringセキュリティを4.0.2にオーバーライドしました。 –

+0

@Remiこれを解決しましたか? – hvgotcodes

答えて

9

デフォルトでは、統合によって "springSecurityFilterChain"という名前のBeanが検索されます。提供されている例では、スタンドアローンの設定が使用されています。つまり、MockMvcはテスト内で提供されたWebApplicationContextを認識しないため、「springSecurityFilterChain」Beanを参照できません。

これを解決する最も簡単な方法は、このようなものを使用することです:

MockMvc mockMvc = MockMvcBuilders 
      // replace standaloneSetup with line below 
      .webAppContextSetup(wac) 
      .alwaysDo(print()) 
      .apply(SecurityMockMvcConfigurers.springSecurity()) 
      .build(); 

あなたが本当に(すでにWebApplicationContextを持っているので、本当に意味がありません)standaloneSetupを使用する場合は、あなたを

@Autowired 
FilterChainProxy springSecurityFilterChain; 

@Before 
public void startMocks(){ 
    controller = wac.getBean(RecipesController.class); 

    MockMvc mockMvc = MockMvcBuilders 
      .standaloneSetup(controller) 
      .alwaysDo(print()) 
      .apply(SecurityMockMvcConfigurers.springSecurity(springSecurityFilterChain)) 
      .build(); 

    MockitoAnnotations.initMocks(this); 
} 
+0

私が間違っているかどうか教えてください。しかし、standaloneSetupを使用することは、Mockを内部に注入できるようにコントローラを十分に制御する唯一の方法です。それとも別の方法がありますか? –

+0

サービスのモックを提供するテスト構成を作成できます。次に、実際のサービスを持つ構成を除外します。あるいは、両方の設定を使用して、サービスの模擬バージョンで '@ Primary'をマークすることもできます。期待値を設定し、模擬サービスを '@ Autowire'できることを確認するには、 –

関連する問題