2017-01-16 38 views
0

我想測試我的控制器,它具有@PreAuthorize,也有服務,我想嘲笑春季安全,測試MVC和模擬服務

PlayerController.java

@RestController 
@RequestMapping(value = "/player") 
public class PlayerController { 
    @Autowired 
    private PlayerService playerService; 

    @PreAuthorize("hasAuthority('ADMIN')") 
    @RequestMapping(value = "/all", method = RequestMethod.GET, produces = "application/json") 
    public 
    @ResponseBody 
    ResponseEntity<List<String>> loadByAdmin() 
    throws Exception { 
    return new ResponseEntity<>(playerService.getPlayers(), HttpStatus.OK); 
    } 
} 

PlayerServiceImpl.java

@Service 
public class PlayerServiceImpl implements PlayerService{ 
    @Autowired 
    private PlayerRepo playerRepo; 

    @Transactional(readOnly = true) 
    public List<String> getPlayers()() { 
    return playerRepo.findAll(); 
    } 
} 

首先嚐試:在這種情況下 - 測試工程,但正如你可以看到authoritySOMEONE所以它應該是失敗的,因爲只有權威0123訪問。

@RunWith(SpringJUnit4ClassRunner.class) 
@WebAppConfiguration 
@ContextConfiguration(classes = {WebAppConfig.class, SecurityConfiguration.class}) 
public class PlayerControllerTest { 
    private MockMvc mockMvc; 

    @Autowired 
    private FilterChainProxy springSecurityFilterChain; 

    @Mock 
    private PlayerService playerService; 

    @InjectMocks 
    private PlayerController playerController; 

    @Test 
    public void loadByAdmin() 
    throws Exception { 
    Player player = new player(); 
    when(playerService.getPlayers()).thenReturn(Collections.singletonList(player)); 

    mockMvc.perform(get("/circuit/all").with(user("adm").password("123") 
     .authorities(new SimpleGrantedAuthority("SOMEONE"))) //not failed 
     .contentType(MediaType.APPLICATION_JSON)) 
     .andExpect(status().isOk()); 

    verify(playerService, times(1)).getPlayers(); 
    verifyNoMoreInteractions(playerService); 
    } 


    @Before 
    public void setUp() { 
    MockitoAnnotations.initMocks(this); 

    mockMvc = MockMvcBuilders 
     .standaloneSetup(playerController) 
     .apply(SecurityMockMvcConfigurers.springSecurity(springSecurityFilterChain)) 
     .build(); 
} 

第二個嘗試:所以我嘗試另一種方法,它的工作原理適合不同的主管部門,但在這種情況下,我不能嘲笑PlayerService

@RunWith(SpringJUnit4ClassRunner.class) 
@WebAppConfiguration 
@ContextConfiguration(classes = {WebAppConfig.class, SecurityConfiguration.class}) 
public class PlayerControllerTest { 
    private MockMvc mockMvc; 

    @Autowired 
    private WebApplicationContext wac; 

    @Mock 
    private PlayerService playerService; 

    @InjectMocks 
    private PlayerController playerController; 

    @Test 
    public void loadByAdmin() 
    throws Exception { 
    Player player = new player(); 
    when(playerService.getPlayers()).thenReturn(Collections.singletonList(player)); //not mocked 

    mockMvc.perform(get("/circuit/all").with(user("adm").password("123") 
     .authorities(new SimpleGrantedAuthority("ADMIN"))) 
     .contentType(MediaType.APPLICATION_JSON)) 
     .andExpect(status().isOk()); 

    verify(playerService, times(1)).getPlayers(); //no interaction 
    verifyNoMoreInteractions(playerService); //no interaction 
    } 


    @Before 
    public void setUp() { 
    MockitoAnnotations.initMocks(this); 

    this.mockMvc.webAppContextSetup(wac) 
      .apply(springSecurity()) 
      .build(); 
} 

那麼,我能爲模擬PlayerService做並測試授權?

+0

嘗試調用MockitoAnnotations.initMocks(本);之後this.mockMvc ..... build() – pbielicki

回答

0

已經解決了反射

@RunWith(SpringJUnit4ClassRunner.class) 
@WebAppConfiguration 
@ContextConfiguration(classes = {WebAppConfig.class}) 
public class PlayerControllerTest { 
    private MockMvc mockMvc; 

    @Mock 
    private PlayerService playerService; 

    @Autowired 
    private PlayerController playerController; 

    @Autowired 
    private FilterChainProxy springSecurityFilterChain; 

    @Test 
    public void loadByAdmin() 
    throws Exception { 
    Player player = new player(); 
    when(playerService.getPlayers()).thenReturn(Collections.singletonList(player)); //success 

    mockMvc.perform(get("/circuit/all").with(user("adm").password("123") 
     .authorities(new SimpleGrantedAuthority("ADMIN"))) 
     .contentType(MediaType.APPLICATION_JSON)) 
     .andExpect(status().isOk()); 

    verify(playerService, times(1)).getPlayers(); //was called 
    verifyNoMoreInteractions(playerService); 
    } 


    @Before 
    public void setUp() { 
    MockitoAnnotations.initMocks(this); 

    this.mockMvc = MockMvcBuilders.standaloneSetup(playerController) 
     .apply(springSecurity(springSecurityFilterChain)).build(); 

    ReflectionTestUtils.setField(playerController, "playerService", playerService); 
} 
0

您能向我們展示PlayerService impl嗎?

你也可以嘗試@Autowire on playerService並在setUp方法中添加一個palyer,在@After刪除該玩家後,對具有管理員權限的玩家進行檢查。由於這是一個@Autowire應該工作的集成測試。

+0

添加PlayerServiceImpl,但@Autowired無法使用,因爲PlayerServiceImpl與數據庫一起工作,當它調用getPlayers時,它從db – Komdosh

+0

獲得真實數據,然後您可以嘗試使用@ RunWith(MockitoJUnitRunner.class)或者將playerService類實例化爲playerService = Mockito.mock(PlayerService.class); –

+0

'@Mock private PlayerService player' with'MockitoAnnotations.initMocks(this);'它等於'playerService = Mockito.mock(PlayerService.class); ' – Komdosh