Pegas @WithMockUser dan request.IsUserInRole()

Saya menggunakan:

request.IsUserInRole("ADMIN")

di salah satu pengontrol saya untuk menentukan respons terhadap permintaan tersebut. Saya mencoba mengejek permintaan dalam pengujian saya seperti:

@Mock
private HttpServletRequest httpRequest;

dan untuk menggunakan anotasi Springs @WithMockUser:

@Test
@WithMockUser(roles={"USER, ADMIN"})
public void getAccountsTest() throws Exception {...}

Keduanya tidak berhasil.

Pertanyaan 1: Bagaimana cara meniru request.IsUserInRole("ADMIN") dalam pengujian JUnit?

Pertanyaan 2: Apa pengaruh @WithMockUser terhadap permintaan dan request.IsUserInRole("ADMIN")?

Terima kasih dan salam

---- sunting ----

"Tidak berhasil" berarti saya memiliki metode pengujian:

@Test
@WithMockUser(username = "user", roles={"USER"})
public void getAccountsReturnForbiddenTest() throws Exception {
    mockMvc.perform(get("/accounts/"))
        .andExpect(status().isForbidden());
}

yang seharusnya mengembalikan 403, tidak diperbolehkan karena pengontrol:

@RequestMapping(method=RequestMethod.GET)
@PreAuthorize("hasRole('ADMIN')")
public ResponseEntity<PagedResources<AccountResource>> getAccounts(...){...}

Tapi permintaannya mengembalikan 200, oke.

Dan saya menggunakan Spring Boot 1.4.1.

---- edit 2 ----

Kelas Tes JUnit saya:

@Transactional
@ContextConfiguration
public class AccountControllerTestDoc extends AbstractControllerTest {

    @InjectMocks
    private AccountController accountController;

    @Mock
    private AccountService accountService;

    private String uriBase = ""; 

    @Before
    public void setup() {
        // Initialize Mockito annotated components
        MockitoAnnotations.initMocks(this);
        // Prepare the Spring MVC Mock components for standalone testing
        setup(accountController);
    }

    @Test
    @WithMockUser(username = "user", roles={"USER"})
    public void getAccountsReturnForbiddenTest() throws Exception {
        String uri = uriBase + "/accounts";
        mockMvc.perform(get(uri))
            .andExpect(status().isForbidden());
    }

}

dengan AbstrakControllerTest:

@WebAppConfiguration
public abstract class AbstractControllerTest extends AbstractTest  {

    protected MockMvc mockMvc;

    @Autowired
    protected WebApplicationContext wac;

    protected void setup() {
        mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
    }

    protected void setup(BaseController controller) {
        mockMvc = MockMvcBuilders.standaloneSetup(controller))
                .build();
    }
}

dan Tes Abstrak:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public abstract class AbstractTest {

    protected Logger LOG = LoggerFactory.getLogger(this.getClass());

}

---- solusi ----

MockMvc standaloneSetup tidak mengetahui konteks aplikasi web dan oleh karena itu tidak mengetahui rantai filter keamanan. Kita harus mengatur MockMvc dengan konteks aplikasi web dan rantai filter keamanan untuk dapat menguji aspek keamanan.

Inilah solusi saya yang sekarang berfungsi, saya mengedit AbstrakControllerTest:

@WebAppConfiguration
public abstract class AbstractControllerTest extends AbstractTest  {

    protected MockMvc mockMvc;

    @Autowired
    protected WebApplicationContext wac;

    @Autowired
    FilterChainProxy springSecurityFilterChain;

    protected void setup() {
        mockMvc = MockMvcBuilders
            .webAppContextSetup(wac)
            .addFilters(springSecurityFilterChain)
            .build();
    }

    protected void setup(BaseController controller) {
        mockMvc = MockMvcBuilders.standaloneSetup(controller))
                .build();
    }
}

person user1337    schedule 17.10.2016    source sumber
comment
Tidak berhasil berarti...   -  person chrylis -cautiouslyoptimistic-    schedule 17.10.2016
comment
Maaf, Tidak berfungsi berarti saya menjalankan permintaan get pada metode aman tanpa peran admin dan status pengembalian bukan 403 yang diharapkan (tidak diotorisasi) tetapi 200 (ok).   -  person user1337    schedule 17.10.2016
comment
Harap tunjukkan cara Anda menyiapkan mockMvc Anda.   -  person chrylis -cautiouslyoptimistic-    schedule 17.10.2016
comment
Saya punya kasus serupa dan ini berhasil untuk saya stackoverflow.com/a/32777599/4614788   -  person Glenn Van Schil    schedule 15.05.2017


Jawaban (1)


Anda harus menambahkan springSecurityFilterChain saat membuat MockMvc

protected MockMvc mockMvc;

@Autowired
protected WebApplicationContext wac;

@Autowired
protected Filter springSecurityFilterChain;

protected void setup() {
    mockMvc = MockMvcBuilders
   .webAppContextSetup(wac)
   .addFilters(springSecurityFilterChain)
   .build();
}
person shazin    schedule 17.10.2016
comment
Terima kasih atas jawabannya! Sedikit lebih banyak latar belakang mengenai pengaturan mandiri untuk MockMvc dari stackoverflow.com/a/34316901/3139759 Saya menambahkan solusi di awal saya pos. - person user1337; 17.10.2016