繁体   English   中英

状态404-MockMvc授权-春季启动REST文档

[英]Status 404 - MockMvc Authorization - Spring boot REST Docs

我有一个控制器

SmsMessageController.java

@Slf4j
@RestController
@RequestMapping("/luxsms/message")
public class SmsMessageController {

private static final String STRING_REQUEST_ACCEPTED = " ";

private SmsStatusService smsStatusService;

private SmsMessageService smsMessageService;

private TaskExecutor taskExecutor;

private ApplicationContext context;

@Autowired
public SmsMessageController(SmsStatusService smsStatusService, SmsMessageService smsMessageService,
        TaskExecutor taskExecutor, ApplicationContext context) {
    this.smsStatusService = smsStatusService;
    this.smsMessageService = smsMessageService;
    this.taskExecutor = taskExecutor;
    this.context = context;
}

@GetMapping("/get/{id}")
public ResponseEntity<SmsMessageDto> get(@PathVariable("id") long id) {

    ResponseEntity<SmsMessageDto> toReturn = null;

    Optional<SmsMessage> byId = smsMessageService.findById(id);
    if (byId.isPresent()) {

        SmsMessageDto smsMessageDto = new SmsMessageDto(byId.get());
        toReturn = new ResponseEntity<>(smsMessageDto, HttpStatus.OK);

    } else {
        toReturn = new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }
    return toReturn;

}

我的测试类SmsMessageControllerTest.java与MockMvc方法:

 @SpringBootTest
@AutoConfigureMockMvc
@RunWith(MockitoJUnitRunner.class)
@WebMvcTest(SmsMessageController.class)
public class SmsMessageControllerTest {

@Autowired
private static final String SERVER_URL = "http://localhost:5050";
private static final String PASSWORD = "pass";
private static final String LUXUSER = "user";
private static final String ROLES = "Admin";

private MockMvc mockMvc;

@Rule
public JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation();

@Mock
SmsMessageService smsMessageService;

@Before
public void before() throws IllegalAccessException {
    mockMvc = MockMvcBuilders.standaloneSetup(smsMessageService)
            .apply(MockMvcRestDocumentation.documentationConfiguration(this.restDocumentation))
            .build();
}

 @Test
 public void testShouldGetMessageWithIdNumberTwo() throws Exception {
            Base64.Encoder encoder = Base64.getEncoder();
            String encoding = encoder.encodeToString((LUXUSER + ":" + PASSWORD).getBytes());

    this.mockMvc.perform(MockMvcRequestBuilders.get("/luxsms/message/get/2").header("Authorization", "Basic " + encoding)
            .accept(MediaType.ALL))
            .andExpect(status().isOk())
            .andExpect(MockMvcResultMatchers.content().string("{\"smsStatusId\": \"test\",\"receiver\": \"123456789\", \"databaseId\": 2}"))
            .andDo(MockMvcRestDocumentation.document("SmsMessageController/get"));
}

和我的日志:

10:07:38.690 [main] DEBUG org.hibernate.validator.internal.engine.ValidatorFactoryImpl - HV000234: Using org.hibernate.validator.internal.engine.scripting.DefaultScriptEvaluatorFactory as ValidatorFactory-scoped script evaluator factory.
10:07:38.743 [main] INFO org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter - Looking for @ControllerAdvice: org.springframework.test.web.servlet.setup.StubWebApplicationContext@7a5ceedd
10:07:38.799 [main] DEBUG org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver - Looking for exception mappings: org.springframework.test.web.servlet.setup.StubWebApplicationContext@7a5ceedd
10:07:38.855 [main] DEBUG org.springframework.test.web.servlet.TestDispatcherServlet - Initializing servlet ''
10:07:38.857 [main] INFO org.springframework.mock.web.MockServletContext - Initializing Spring FrameworkServlet ''
10:07:38.857 [main] INFO org.springframework.test.web.servlet.TestDispatcherServlet - FrameworkServlet '': initialization started
10:07:38.860 [main] DEBUG org.springframework.test.web.servlet.TestDispatcherServlet - Unable to locate MultipartResolver with name 'multipartResolver': no multipart request handling provided
10:07:38.861 [main] DEBUG org.springframework.test.web.servlet.TestDispatcherServlet - Using LocaleResolver [org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver@63a5e46c]
10:07:38.861 [main] DEBUG org.springframework.test.web.servlet.TestDispatcherServlet - Using ThemeResolver [org.springframework.web.servlet.theme.FixedThemeResolver@7e8e8651]
10:07:38.861 [main] DEBUG org.springframework.test.web.servlet.TestDispatcherServlet - Using RequestToViewNameTranslator [org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator@49ef32e0]
10:07:38.861 [main] DEBUG org.springframework.test.web.servlet.TestDispatcherServlet - Using FlashMapManager [org.springframework.web.servlet.support.SessionFlashMapManager@271f18d3]
10:07:38.861 [main] DEBUG org.springframework.test.web.servlet.TestDispatcherServlet - Published WebApplicationContext of servlet '' as ServletContext attribute with name [org.springframework.web.servlet.FrameworkServlet.CONTEXT.]
10:07:38.861 [main] INFO org.springframework.test.web.servlet.TestDispatcherServlet - FrameworkServlet '': initialization completed in 4 ms
10:07:38.861 [main] DEBUG org.springframework.test.web.servlet.TestDispatcherServlet - Servlet '' configured successfully
10:07:38.907 [main] DEBUG org.springframework.test.web.servlet.TestDispatcherServlet - DispatcherServlet with name '' processing GET request for [/luxsms/message/get/2]
10:07:38.909 [main] DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Looking up handler method for path /luxsms/message/get/2
10:07:38.910 [main] DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Did not find handler method for [/luxsms/message/get/2]
10:07:38.910 [main] WARN org.springframework.web.servlet.PageNotFound - No mapping found for HTTP request with URI [/luxsms/message/get/2] in DispatcherServlet with name ''
10:07:38.910 [main] DEBUG org.springframework.test.web.servlet.TestDispatcherServlet - Successfully completed request

java.lang.AssertionError: Status 
Expected :200
Actual   :404
 <Click to see difference>


    at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:55)
    at org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:82)
    at org.springframework.test.web.servlet.result.StatusResultMatchers.lambda$matcher$9(StatusResultMatchers.java:617)
    at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:179)
    at pl.luxmed.luxsms.controller.SmsMessageControllerTest.testShouldGetMessageWithIdNumberOne(SmsMessageControllerTest.java:85)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.springframework.restdocs.JUnitRestDocumentation$1.evaluate(JUnitRestDocumentation.java:63)
    at org.junit.rules.RunRules.evaluate(RunRules.java:20)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    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.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.mockito.internal.runners.DefaultInternalRunner$1.run(DefaultInternalRunner.java:79)
    at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:85)
    at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:39)
    at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:163)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

问题出在授权恕我直言。 在POSTMAN中,一切正常。 我的方法可以编码,因为邮递员是一样的。 也许有人有这样的问题?

PS我写了简单的客户端,也可以工作,但是我必须用RESTdocs实现MockMvc。

@Test
    public void get(){
        String url = SERVER_URL + "/luxsms/message/get";

        ArrayList<String> ListOfId = new ArrayList<>();
        ListOfId.add(0, "/0");
        ListOfId.add(1, "/4");
        ListOfId.add(2, "/5");
        ListOfId.add(3, "/6");
        for (String param : ListOfId) {

            String urlWithParam = url + param;

            Base64.Encoder encoder = Base64.getEncoder();
            String encoding = encoder.encodeToString((LUXUSER + ":" + PASSWORD).getBytes());

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.add("Authorization", "Basic " + encoding);
            headers.add("Content-Type", "text/html");
            headers.add("charset", "utf-8");

            HttpEntity<String> entity = new HttpEntity<String>(" ", headers);

            StringHttpMessageConverter element =
                    new StringHttpMessageConverter(Charset.forName("UTF-8"));
            RestTemplate restTemplate = new RestTemplate();
            restTemplate.getMessageConverters().add(0, element);

            ResponseEntity<String> exchange = restTemplate.exchange(urlWithParam, HttpMethod.GET, entity, String.class);

            System.out.println(exchange.getBody());
            System.out.println();
        }
    }
 @SpringBootTest
@AutoConfigureMockMvc
@RunWith(MockitoJUnitRunner.class)
@WebMvcTest(SmsMessageController.class)
public class SmsMessageControllerTest {

@Autowired
private static final String SERVER_URL = "http://localhost:5050";
private static final String PASSWORD = "pass";
private static final String LUXUSER = "user";
private static final String ROLES = "Admin";

private MockMvc mockMvc;

@Rule
public JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation();

@Mock
SmsMessageService smsMessageService;

@Before
public void before() throws IllegalAccessException {
    mockMvc = MockMvcBuilders.standaloneSetup(smsMessageService)
            .apply(MockMvcRestDocumentation.documentationConfiguration(this.restDocumentation))
            .build();
}

 @Test
 public void testShouldGetMessageWithIdNumberTwo() throws Exception {
            Base64.Encoder encoder = Base64.getEncoder();
            String encoding = encoder.encodeToString((LUXUSER + ":" + PASSWORD).getBytes());

    this.mockMvc.perform(MockMvcRequestBuilders.get("/luxsms/message/get/2").header("Authorization", "Basic " + encoding)
            .accept(MediaType.ALL))
            .andExpect(status().isOk())
            .andExpect(MockMvcResultMatchers.content().string("{\"smsStatusId\": \"test\",\"receiver\": \"123456789\", \"databaseId\": 2}"))
            .andDo(MockMvcRestDocumentation.document("SmsMessageController/get"));
}

此测试有几处错误/有缺陷的地方。

  1. 结合使用@SpringBootTest和切片@WebMvcTest不能同时使用两者
  2. 使用MockitoJUnitRunner运行测试
  3. @WebMvcTest暗示AutoConfigureMockMvc
  4. static字段上的@Autowirede将不起作用。
  5. 手动设置MockMvc然后为什么使用@WebMvcTest@AutoConfigureMockMvc
  6. 使用@Mock代替Spring Boot管理的@MockBean

话虽这么说,您的测试应该看起来像这样。

@RunWith(SpringRunner)
@WebMvcTest(SmsMessageController.class)
@AutoConfigureRestDocs
public class SmsMessageControllerTest {

  private static final String PASSWORD = "pass";
  private static final String LUXUSER = "user";
  private static final String ROLES = "Admin";

  @Autowired
  private MockMvc mockMvc;

  @MockBean
  private SmsMessageService smsMessageService;

   @Test
   public void testShouldGetMessageWithIdNumberTwo() throws Exception {
       Base64.Encoder encoder = Base64.getEncoder();
       String encoding = encoder.encodeToString((LUXUSER + ":" + PASSWORD).getBytes());

    this.mockMvc.perform(MockMvcRequestBuilders.get("/luxsms/message/get/2").header("Authorization", "Basic " + encoding)
            .accept(MediaType.ALL))
            .andExpect(status().isOk())
            .andExpect(MockMvcResultMatchers.content().string("{\"smsStatusId\": \"test\",\"receiver\": \"123456789\", \"databaseId\": 2}"))
            .andDo(MockMvcRestDocumentation.document("SmsMessageController/get"));
}

另请参阅有关自动配置的Spring REST Docs的《 Spring Boot参考指南》部分以及有关“ 模拟Bean”的部分

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM