1

I work to test a RESTful API and the test method is provided,

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
@AutoConfigureMockMvc
public class AppointmentAPITest {


    /*
     * we need a system to simulate this behavior without starting a
     * full HTTP server. MockMvc is the Spring class that does that.
     * */
    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private AppointmentAPI api;


    @Test
    public void getAppointments_findById() throws Exception {


        Appointment appoint1 = new Appointment(Date.valueOf("2018-09-01"), Time.valueOf("01:12:16"), "Vania Vong", 125.5);
        Appointment appoint2 = new Appointment(Date.valueOf("2018-10-15"), Time.valueOf("08:30:00"), "Maria Wang", 275);


        given(api.findById(1L)).willReturn(ResponseEntity.ok(appoint1));
        given(api.findById(2L)).willReturn(ResponseEntity.ok(appoint2));

        mockMvc.perform(get("/api/v1/appointments/1")

                .contentType(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$", hasSize(1)))
                .andExpect(jsonPath("$[0].name_of_doctor", is(appoint1.getName_of_doctor())));
    }}

The entity is provided below,

@Entity
public class Appointment {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column
    private java.sql.Time created_at;

    @Column
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private java.sql.Date appointment_date;

    @Column
    @Size(min = 3, max = 20)
    private String name_of_doctor;

    @Embedded
    private Status status;

    @Column
    private double price;

    public Appointment() {

    }

    public Appointment(Date appointment_date, Time created_at, String name_of_doctor, double price) {

        this.created_at = created_at;
        this.appointment_date = appointment_date;
        this.name_of_doctor = name_of_doctor;
        this.price = price;
    }

    public Appointment(String name_of_doctor, Status status, double price) {

        this.name_of_doctor = name_of_doctor;
        this.status = status;
        this.price = price;
    }


    public Appointment(String name_of_doctor, double price) {

        this.name_of_doctor = name_of_doctor;
        this.price = price;
    }


    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Time getCreated_at() {
        return created_at;
    }

    public void setCreated_at(Time created_at) {
        this.created_at = created_at;
    }

    public Date getAppointment_date() {
        return appointment_date;
    }

    public void setAppointment_date(Date appointment_date) {
        this.appointment_date = appointment_date;
    }

    public String getName_of_doctor() {
        return name_of_doctor;
    }

    public void setName_of_doctor(String name_of_doctor) {
        this.name_of_doctor = name_of_doctor;
    }

    public Status getStatus() {
        return status;
    }

    public void setStatus(Status status) {
        this.status = status;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }


    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Appointment)) return false;
        Appointment that = (Appointment) o;
        return Double.compare(that.getPrice(), getPrice()) == 0 &&
                Objects.equals(getId(), that.getId()) &&
                Objects.equals(getCreated_at(), that.getCreated_at()) &&
                Objects.equals(getAppointment_date(), that.getAppointment_date()) &&
                Objects.equals(getName_of_doctor(), that.getName_of_doctor()) &&
                Objects.equals(getStatus(), that.getStatus());
    }

    @Override
    public int hashCode() {

        return Objects.hash(getId(), getCreated_at(), getAppointment_date(), getName_of_doctor(), getStatus(), getPrice());
    }

    @Override
    public String toString() {
        return "Appointment{" +
                "id=" + id +
                ", created_at=" + created_at +
                ", appointment_date=" + appointment_date +
                ", name_of_doctor='" + name_of_doctor + '\'' +
                ", status=" + status +
                ", price=" + price +
                '}';
    }
}

The API end-point is provided below,

  @RestController
  @RequestMapping("/api/v1/appointments")

public class AppointmentAPI {


    @Autowired
    AppointmentServiceImpl service;
@GetMapping("/{id}")
    public ResponseEntity<Appointment> findById(@PathVariable Long id) {


        Optional<Appointment> appointment = service.findById(id);

        if (!appointment.isPresent()) {
            ResponseEntity.badRequest().build();
        }

        return ResponseEntity.ok(appointment.get());
    }



   // ..............
   }

When I run the test, I get the error provided,

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalArgumentException: Name for argument type [java.lang.Long] not available, and parameter name information not found in class file either.

    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1013)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882)
    at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:71)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
    at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.java:166)
    at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:133)
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:133)
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:133)
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:133)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:133)
    at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:182)
    at com.appoint.manager.Appointment.api.AppointmentAPITest.getAppointments_findById(AppointmentAPITest.java:66)
    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:74)
    at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84)
    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.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)
Caused by: java.lang.IllegalArgumentException: Name for argument type [java.lang.Long] not available, and parameter name information not found in class file either.
    at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.updateNamedValueInfo(AbstractNamedValueMethodArgumentResolver.java:172)
    at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.getNamedValueInfo(AbstractNamedValueMethodArgumentResolver.java:149)
    at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:98)
    at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:126)
    at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:166)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:134)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:800)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1038)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005)
    ... 51 more

Why does it saying the Name for argument type [java.lang.Long] not available, and parameter name information not found in class?

2
  • 1
    show your request mapping for /api/v1/appointments/ Commented Feb 11, 2019 at 10:53
  • @MaciejKowalski its provided now Commented Feb 11, 2019 at 10:54

1 Answer 1

3

Add the name to the annotation in the method parameter:

findById(@PathVariable("id") Long id)
Sign up to request clarification or add additional context in comments.

2 Comments

This is already there public ResponseEntity<Appointment> findById(@PathVariable Long id). Do you mean I need to add the method parameter in the test method as well? I tried it and that doesn't work out.
Just the name attribute of @PathVariable

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.