2017-07-17 16 views
0

JUnit、Mockito、Springテスト、Spring Securityテストを使用して、スプリングレストコントローラクラスをテストしようとしています。以下は私がテストを行っているレストコントローラクラスです。Mockito失敗:実際には、このモックとの相互作用はゼロです。

@RestController 
public class EmployeeRestController { 

    @Autowired 
    private EmployeeService employeeService; 

    @PreAuthorize("hasAnyRole('ROLE_EMPSUPEADM')") 
    @RequestMapping(value = "/fetch-timezones", method = RequestMethod.GET) 
    public ResponseEntity<List<ResponseModel>> fetchTimeZones() { 
     List<ResponseModel> timezones = employeeService.fetchTimeZones(); 
     return new ResponseEntity<>(timezones, HttpStatus.OK); 
    } 

} 

以下は私のテストクラスです。

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(classes = {SpringConfiguration.class}) 
@WebAppConfiguration 
public class EmployeeRestControllerUnitTest { 

private MockMvc mockMvc; 

@Autowired 
private WebApplicationContext webApplicationContext; 

@Mock 
private EmployeeService employeeService; 

@InjectMocks 
private EmployeeRestController employeeRestController; 

@Before 
public void init() { 
    MockitoAnnotations.initMocks(this); 
    Mockito.reset(employeeService); 
    mockMvc = MockMvcBuilders 
       .webAppContextSetup(webApplicationContext) 
       .build(); 
} 

@Test 
@WithMockUser(roles = {"EMPSUPEADM"}) 
public void testFetchTimezones() { 
    try { 
     mockMvc.perform(get("/fetch-timezones")) 
      .andExpect(status().isOk())    
      .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8)) 
      .andExpect(jsonPath("$", hasSize(4))); 
     verify(emploeeService, times(1)).fetchTimeZones(); 
     verifyNoMoreInteractions(employeeService); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

}

私は多くのチュートリアルを参照のうえで上記のテストクラスを作りました。問題は私がすべてをはっきりと理解することができないことです。だから、私は次の疑問を持っている。

  1. 私はEmployeeServiceのモックを作成し、なぜ私は、次の失敗を得ている、@InjectMocksを使用してEmployeeRestControllerに注入しています。

    Wanted but not invoked: 
    careGroupService.fetchTimeZones(); 
    -> at com.example.api.test 
    .restcontroller.EmployeeRestControllerUnitTest 
    .testFetchTimezones(EmployeeRestControllerUnitTest.java:73) 
    Actually, there were zero interactions with this mock. 
    
  2. どうMockMvcBuilders.webAppContextSetup(webApplicationContext).build()を行います。正確に動作します。

  3. 私は、MockMvcBuilders.standaloneSetup(employeeRestController)は個々のコントローラクラスをテストするためのものであり、この方法ではスプリング設定が利用できないことを知っています。この方法のためにどのようにスプリング構成を提供できますか?

  4. 最後に、このコードはどのようにして動作しますか:Mockito.reset(employeeService);働く

答えて

1

1)あなたは

verify(emploeeService, times(1)).fetchTimeZones(); 

のために確認しますが、あなたはそれのためのセットアップモック行動を(あなたがmockMvc.perform(get("/fetch-timezones"))を呼び出す前に)しませんでした。

List<ResponseModel> timezones = new ArrayList<>(); 
when(emploeeService.fetchTimeZones()).thenReturn(timezones); 

2)コンテキストからMockMvcを作成します。 mockmvcはWebコンテナをエミュレートし、どこでも可能ですが模擬を使用しますが、HTTPコールをサポートし、コントローラを呼び出す可能性を与えました。

サーバーを実行しているのオーバーヘッドなしには、ディスパッチャサーブレットと、必要なすべてのMVCコンポーネントを立ち上がる は、私たちは、適切なウェブ環境でエンドポイントをテストすることができますが、 。

3)使用:

@MockBean private EmployeeService employeeService; 

あなたは本当のサービスを無効にします。テストクラスから削除してください。実際のサービスはテストで使用されます。 @Mockを使用する代わりに、@MockBeanを使用します。コンテナによってそれのオーバーライド@MockBean、@Mockであなたは反射

や反射とスプリングブートなしでコントローラにこれを注入する必要があります。

@Before 
public void init() { 
    MockitoAnnotations.initMocks(this); 
    Mockito.reset(employeeService); 
    mockMvc = MockMvcBuilders 
       .webAppContextSetup(webApplicationContext) 
       .build(); 
    EmployeeRestController employeeRestController= 
      webAppContext.getBean(EmployeeRestController.class); 
    ReflectionTestUtils.setField(employeeRestController, 
           "employeeService", 
           employeeService); 
} 

4)Mockito.reset(employeeService); - あなたは前にsetuppedすべての行動をリセットします。 Mockにはwhen(), verify()の情報が含まれており、それを制御してリセットを呼び出す - すべての情報を消去する。

+0

お返事ありがとうございます。しかし、私はまだ同じ失敗メッセージを得ています。 – karthi

+0

申し訳ありませんが、私は春のブーツを使用していません。 – karthi

+0

あなたの助けていただきありがとうございます。この[リンク](https://stackoverflow.com/questions/37369768/should-mockito-be-used-with)で提案されている**テストコンテキスト**を提供することで、 -mockmvcs-webappcontext-in-spring-4) – karthi

関連する問題