Skip to content

Instantly share code, notes, and snippets.

@ihoneymon
Created September 17, 2018 03:28
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ihoneymon/636383f4a39125def00464357556fc1b to your computer and use it in GitHub Desktop.
Save ihoneymon/636383f4a39125def00464357556fc1b to your computer and use it in GitHub Desktop.
Spring REST DOCs에서 pathParameters 를 사용하는 경우 `MockMvcRequestBuilders` 를 `RestDocumentationRequestBuilders` 로 변경한다.

[spring] REST Docs 사용중 urlTemplate not found. If you are using MockMvc did you use RestDocumentationRequestBuilders to build the request?

@ActiveProfiles("test")
@RunWith(SpringRunner.class)
@SpringBootTest
public class BookControllerTest {
    private MockMvc mockMvc;
    @Rule
    public JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation();

    @Autowired
    WebApplicationContext wac;
    @MockBean
    BookService bookService;

    @Before
    public void setUp() {
        //mockBookController 내에 Mock 처리된 bookService를 주입하기 위해 반드시 선언해줘야 함
        MockitoAnnotations.initMocks(this);

        this.mockMvc = MockMvcBuilders.webAppContextSetup(wac)
                .apply(documentationConfiguration(this.restDocumentation))
                .alwaysDo(print())
                .build();
    }

    @Test
    public void testOptions() throws Exception {
        this.mockMvc.perform(options("/books").contentType(MediaType.APPLICATION_JSON_UTF8))
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andDo(document("books-options"));
    }

    @Test
    public void testHead() throws Exception {
        Long id = 1L;
        when(bookService.findById(id)).thenReturn(Optional.of(new Book("test-book", "test-isbn13", "test-isbn10")));

        this.mockMvc.perform(head("/books/{id}", 1).contentType(MediaType.APPLICATION_JSON_UTF8))
                .andExpect(MockMvcResultMatchers.status().isNoContent())
                .andDo(document("books-head"));
    }

    @Test
    public void testGet() throws Exception {
        Long id = 1L;
        when(bookService.findById(1L)).thenReturn(Optional.of(new Book("test-book", "test-isbn13", "test-isbn10")));

        this.mockMvc.perform(get("/books/{id}", id).contentType(MediaType.APPLICATION_JSON_UTF8))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.data.name", Is.is("test-book")))
                .andExpect(jsonPath("$.data.isbn13", Is.is("test-isbn13")))
                .andExpect(jsonPath("$.data.isbn10", Is.is("test-isbn10")))
                .andDo(document("books-get", pathParameters(
                        parameterWithName("id").description("도서 참조키")
                )));
    }
}

다음과 같이 코드를 짰다. testGet 에서 document 선언을 하는 부분에서 pathParameters 를 추가했더니 다음과 같은 오류 메시지가 출력된다.

java.lang.IllegalArgumentException: urlTemplate not found. If you are using MockMvc did you use RestDocumentationRequestBuilders to build the request?

	at org.springframework.util.Assert.notNull(Assert.java:193)
	at org.springframework.restdocs.request.PathParametersSnippet.extractUrlTemplate(PathParametersSnippet.java:132)
	at org.springframework.restdocs.request.PathParametersSnippet.extractActualParameters(PathParametersSnippet.java:119)
	at org.springframework.restdocs.request.AbstractParametersSnippet.verifyParameterDescriptors(AbstractParametersSnippet.java:95)
	at org.springframework.restdocs.request.AbstractParametersSnippet.createModel(AbstractParametersSnippet.java:79)
	at org.springframework.restdocs.request.PathParametersSnippet.createModel(PathParametersSnippet.java:104)
	at org.springframework.restdocs.snippet.TemplatedSnippet.document(TemplatedSnippet.java:83)
	at org.springframework.restdocs.generate.RestDocumentationGenerator.handle(RestDocumentationGenerator.java:206)
	at org.springframework.restdocs.mockmvc.RestDocumentationResultHandler.handle(RestDocumentationResultHandler.java:55)
	at org.springframework.test.web.servlet.MockMvc$1.andDo(MockMvc.java:183)
	at io.honeymon.springboot.t.bookstore.api.controller.BookControllerTest.testGet(BookControllerTest.java:90)
	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.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:73)
	at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:83)
	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
	at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
	at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
	at org.springframework.restdocs.JUnitRestDocumentation$1.evaluate(JUnitRestDocumentation.java:63)
	at org.junit.rules.RunRules.evaluate(RunRules.java:20)
	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.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)

찾아보니 pathParameters를 사용할거면 MockMvcBuilders 보다 RestDocumentationRequestBuilders를 이용하는 것이 좋다고 한다.

To make the path parameters available for documentation, the request must be built using one of the methods on RestDocumentationRequestBuilders rather than MockMvcRequestBuilders.

코드를 다음과 같이 변경하면 된다.

@Test
public void testGet() throws Exception {
    Long id = 1L;
    when(bookService.findById(1L)).thenReturn(Optional.of(new Book("test-book", "test-isbn13", "test-isbn10")));


    this.mockMvc.perform(MockMvcRequestBuilders.get("/books/{id}", // <1> id).contentType(MediaType.APPLICATION_JSON_UTF8))
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.data.name", Is.is("test-book")))
            .andExpect(jsonPath("$.data.isbn13", Is.is("test-isbn13")))
            .andExpect(jsonPath("$.data.isbn10", Is.is("test-isbn10")))
            .andDo(document("books-get", pathParameters(
                    parameterWithName("id").description("도서 참조키")
            )));
}

@Test
    public void testGet() throws Exception {
        Long id = 1L;
        when(bookService.findById(1L)).thenReturn(Optional.of(new Book("test-book", "test-isbn13", "test-isbn10")));


        this.mockMvc.perform(RestDocumentationRequestBuilders.get("/books/{id}", // <2> id).contentType(MediaType.APPLICATION_JSON_UTF8))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.data.name", Is.is("test-book")))
                .andExpect(jsonPath("$.data.isbn13", Is.is("test-isbn13")))
                .andExpect(jsonPath("$.data.isbn10", Is.is("test-isbn10")))
                .andDo(document("books-get", pathParameters(
                        parameterWithName("id").description("도서 참조키")
                )));
    }
  1. MockMvcRequestBuilders 을 <2> MockMvcRequestBuilders 으로 변경하면 된다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment