Spring-boot WebMvcTest, почему я получаю этот NullPointer, когда предоставляю имитацию UserDetailsService? - PullRequest
0 голосов
/ 09 июля 2020

Я пытаюсь создать несколько @WebMvcTest кейсов при загрузке Spring. У меня есть проверяемый контроллер, и я пытаюсь использовать @WithUserDetails, чтобы я мог протестировать объект Authentication, который передается моему методу контроллера в качестве параметра.

У меня есть собственное расширение UserDetails с именем EmployeeDetails.

Я имитирую свой UserDetailsService с помощью @MockBean, и я заставляю его возвращать настраиваемый объект EmployeeDetails, используя given(userDetailsService.loadUserByUsername(anyString())).willReturn(new EmployeeDetails(employee, account));

Однако, когда я запускаю тест, я получите следующую ошибку:

java.lang.IllegalStateException: Unable to create SecurityContext using @org.springframework.security.test.context.support.WithUserDetails(setupBefore=TEST_METHOD, userDetailsServiceBeanName=userDetailsService, value=someemail@email.com)

    at org.springframework.security.test.context.support.WithSecurityContextTestExecutionListener.createTestSecurityContext(WithSecurityContextTestExecutionListener.java:126)
    at org.springframework.security.test.context.support.WithSecurityContextTestExecutionListener.createTestSecurityContext(WithSecurityContextTestExecutionListener.java:96)
    at org.springframework.security.test.context.support.WithSecurityContextTestExecutionListener.beforeTestMethod(WithSecurityContextTestExecutionListener.java:62)
    at org.springframework.test.context.TestContextManager.beforeTestMethod(TestContextManager.java:289)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
    at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
    at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)
Caused by: java.lang.NullPointerException
    at org.springframework.security.test.context.support.WithUserDetailsSecurityContextFactory.createSecurityContext(WithUserDetailsSecurityContextFactory.java:63)
    at org.springframework.security.test.context.support.WithUserDetailsSecurityContextFactory.createSecurityContext(WithUserDetailsSecurityContextFactory.java:44)
    at org.springframework.security.test.context.support.WithSecurityContextTestExecutionListener.createTestSecurityContext(WithSecurityContextTestExecutionListener.java:123)
    ... 23 more

Что вызывает это? Я не понимаю У меня сложилось впечатление, что издеваемый UserDetailsService должен возвращать объект, который я предоставляю в вызове given. Почему я получаю NullPointer? Может ли кто-нибудь указать мне в правильном направлении?

Спасибо!

Это мой тестовый пример:

@RunWith(SpringRunner.class)
@WebMvcTest(PDPController.class)
@AutoConfigureMockMvc(addFilters = false)
public class PDPControllerTests {

    @Autowired
    private MockMvc mvc;

    @Autowired
    private ObjectMapper objectMapper;

    @MockBean
    private PDPService pdpService;

    @MockBean(name = "userDetailsService")
    private MyUserDetailsService userDetailsService;
    
    //..
    
    @Test
    @WithUserDetails(value = "someemail@email.com", userDetailsServiceBeanName = "userDetailsService")
    public void testSaveBackground_returns_result_from_service() throws Exception {
        PersonalDevelopmentPlan pdp = new PersonalDevelopmentPlan();
        pdp.setEmployee(EMPLOYEE_ID);
        Account account = new Account();
        Employee employee = new Employee();

        given(pdpService.saveBackground(eq(EMPLOYEE_ID), any(), anyInt())).willReturn(pdp);
        given(userDetailsService.loadUserByUsername(anyString())).willReturn(new EmployeeDetails(employee, account));

        mvc.perform(patch(URL_WITH_ID + "/background").secure(true)
                .contentType(MediaType.APPLICATION_JSON)
                .content(objectMapper.writeValueAsString(pdp)))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.employee", Matchers.is(EMPLOYEE_ID)));
    }
    
} 

1 Ответ

1 голос
/ 09 июля 2020
  • Добавьте следующее
    @PostConstruct
    public void setup() {
        Account account = new Account();
        Employee employee = new Employee();
        given(userDetailsService.loadUserByUsername(anyString()))
             .willReturn(new EmployeeDetails(employee, account));
    }
  • И удалите следующую строку изнутри метода тестирования
   given(userDetailsService.loadUserByUsername(anyString()))
             .willReturn(new EmployeeDetails(employee, account));
...