[英]Status 404 - MockMvc Authorization - Spring boot REST Docs
I have a controller 我有一个控制器
SmsMessageController.java 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;
}
and my test class SmsMessageControllerTest.java with MockMvc method: 我的测试类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"));
}
And my logs: 和我的日志:
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)
The problem is with authorization imho. 问题出在授权恕我直言。 In POSTMAN everything works well.
在POSTMAN中,一切正常。 Encoding in my method its ok because is the same in postman.
我的方法可以编码,因为邮递员是一样的。 Maybe somebody had problem like this?
也许有人有这样的问题?
PS I write simple client and works too, but i have to implement MockMvc with RESTdocs. 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"));
}
There are a couple of things wrong/flawed with this test. 此测试有几处错误/有缺陷的地方。
@SpringBootTest
and a slice @WebMvcTest
use either not both @SpringBootTest
和切片@WebMvcTest
不能同时使用两者 MockitoJUnitRunner
MockitoJUnitRunner
运行测试 AutoConfigureMockMvc
is implied by @WebMvcTest
@WebMvcTest
暗示AutoConfigureMockMvc
@Autowirede
on a static
field will not work. static
字段上的@Autowirede
将不起作用。 MockMvc
then why use @WebMvcTest
or @AutoConfigureMockMvc
MockMvc
然后为什么使用@WebMvcTest
或@AutoConfigureMockMvc
@Mock
instead of the Spring Boot managed @MockBean
@Mock
代替Spring Boot管理的@MockBean
That being said your test should look something like this. 话虽这么说,您的测试应该看起来像这样。
@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"));
}
See also the Spring Boot Reference Guide section on autoconfigured Spring REST Docs as well as the section on Mocking Beans 另请参阅有关自动配置的Spring REST Docs的《 Spring Boot参考指南》部分以及有关“ 模拟Bean”的部分
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.