首页 > 解决方案 > Junit Fail 服务总是返回 404

问题描述

尝试以 TDD 方式在 SpringBootProjectApplicationTests 中的测试中传递 JUnit,但它在当时的操作中 test1 始终服务返回 HTTP 代码 404 而不是 HTTP 代码 200

此代码位于github.com/saandeepani/SpringBootJunit位置,请从那里下载以在本地复制问题

请看下面的代码

SpringBootProjectApp.java

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.hateoas.config.EnableHypermediaSupport;
    
    @SpringBootApplication
    @EnableHypermediaSupport(type = EnableHypermediaSupport.HypermediaType.HAL)
    public class SpringBootProjectApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(SpringBootProjectApplication.class, args);
        }
    }

控制器WidgetController.java

    package com.spring.tdd.controller;
    
    import java.net.URI;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.http.ResponseEntity;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RestController;
    
    import com.spring.tdd.data.WidgetEntity;
    import com.spring.tdd.data.WidgetRepository;
    import com.spring.tdd.resources.WidgetResource;
    
    @RestController
    public class WidgetController {
    
        @Autowired
        WidgetRepository widgetRepository;
    
        @PostMapping("/widgets")
        public ResponseEntity<String> CreateWidget(@RequestBody WidgetResource widgetResource) {
    
            WidgetEntity entity = new WidgetEntity();
    
            entity.setProductName(widgetResource.getName());
            entity.setProductDetail(widgetResource.getDescription());
    
            widgetRepository.save(entity);
    
            URI widgets = URI.create("widgets");
            return ResponseEntity.created(widgets).header("MyResponseHeader", "widgetResource").body("Hello World");
    
            // return widgetResource;
    
        }
    
        /*
         * @GetMapping("/widgets") public String getWidget() {
         * 
         * URI widgets = URI.create("widgets"); return
         * ResponseEntity.created(widgets).header("MyResponseHeader",
         * "widgetResource").body("Hello World");
         * 
         * }
         */
    
    }

小部件实体.java

    package com.spring.tdd.data;
    
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.Table;
    import javax.persistence.UniqueConstraint;
    import javax.validation.constraints.NotNull;
    import java.util.Objects;
    
    @Entity
    @Table(uniqueConstraints = @UniqueConstraint(name = "widget_productName_idx", columnNames = "productName"))
    public class WidgetEntity {
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
        @NotNull
        private String productName;
        private String productDetail;
    
        public WidgetEntity() {
        }
    
        public WidgetEntity(final String productName, final String productDetail) {
            this.productName = productName;
            this.productDetail = productDetail;
        }
    
        public Long getId() {
            return id;
        }
    
        public void setId(final Long id) {
            this.id = id;
        }
    
        public String getProductName() {
            return productName;
        }
    
        public void setProductName(final String productName) {
            this.productName = productName;
        }
    
        public String getProductDetail() {
            return productDetail;
        }
    
        public void setProductDetail(final String productDetail) {
            this.productDetail = productDetail;
        }
    
        @Override
        public boolean equals(final Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            final WidgetEntity that = (WidgetEntity) o;
            return Objects.equals(productName, that.productName);
        }
    
        @Override
        public int hashCode() {
    
            return Objects.hash(productName);
        }
    
        @Override
        public String toString() {
            return "WidgetEntity{" +
                    "id=" + id +
                    ", productName='" + productName + '\'' +
                    ", productDetail='" + productDetail + '\'' +
                    '}';
        }
    }

WidgetRepository.java

    package com.spring.tdd.data;
    
    import org.springframework.data.jpa.repository.JpaRepository;
    import org.springframework.stereotype.Repository;
    
    @Repository
    public interface WidgetRepository extends JpaRepository<WidgetEntity, Long> {
    
    }

小部件资源.java

    package com.spring.tdd.resources;
    
    
    import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
    import com.fasterxml.jackson.annotation.JsonInclude;
    import org.springframework.hateoas.core.Relation;
    
    import java.util.Objects;
    
    @JsonIgnoreProperties(ignoreUnknown = true)
    @JsonInclude(JsonInclude.Include.NON_NULL)
    @Relation(value = "widget", collectionRelation = "widgets")
    public class WidgetResource {
    
        private String name;
        private String description;
    
        public WidgetResource() {
        }
    
        public WidgetResource(final String name, final String description) {
            this.name = name;
            this.description = description;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(final String name) {
            this.name = name;
        }
    
        public String getDescription() {
            return description;
        }
    
        public void setDescription(final String description) {
            this.description = description;
        }
    
        @Override
        public boolean equals(final Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            final WidgetResource that = (WidgetResource) o;
            return Objects.equals(name, that.name) &&
                    Objects.equals(description, that.description);
        }
    
        @Override
        public int hashCode() {
    
            return Objects.hash(name, description);
        }
    
        @Override
        public String toString() {
            return "WidgetResource{" +
                    "name='" + name + '\'' +
                    ", description='" + description + '\'' +
                    '}';
        }
    }

SpringBootProjectApplicationTests

    package com.spring.tdd;
    
    import org.junit.Ignore;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.http.MediaType;
    import org.springframework.mock.web.MockHttpServletResponse;
    import org.springframework.test.context.junit4.SpringRunner;
    import org.springframework.test.web.servlet.MockMvc;
    
    import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
    import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
    import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
    import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest
    @AutoConfigureMockMvc
    public class SpringBootProjectApplicationTests {
    
        @Autowired
        private MockMvc mvc;
    
        @Test
        public void can_save_and_retrieve_widgets() throws Exception {
            // Given
            final StringBuilder body = new StringBuilder();
            body.append ("{");
            {
                body.append("\"name\":\"WidgetX\"").append(",");
                body.append("\"description\":\"A brand new Widget\"");
            }
            body.append("}");
    
    
            // When
            final MockHttpServletResponse response = mvc.perform(post("/widgets")
            .contentType(MediaType.APPLICATION_JSON)
            .content(body.toString()))
                    .andExpect(status().isCreated())
                    .andReturn().getResponse();
    
            final String location = response.getHeaderValue("location").toString();
    
            // Then
            mvc.perform(get(location)
                    .contentType(MediaType.APPLICATION_JSON))
                    .andExpect(status().isOk())
                    .andExpect(jsonPath("$.name").value("WidgetX"))
                    .andExpect(jsonPath("$.description").value("A brand new Widget"));
    
        }
    
        @Test
        public void new_resources_have_valid_self_link() throws Exception {
            // Given
            final StringBuilder body = new StringBuilder();
            body.append ("{");
            {
                body.append("\"name\":\"WidgetY\"").append(",");
                body.append("\"description\":\"Another brand new Widget\"");
            }
            body.append("}");
    
    
            // When
            final MockHttpServletResponse response = mvc.perform(post("/widgets")
                    .contentType(MediaType.APPLICATION_JSON)
                    .content(body.toString()))
                    .andExpect(status().isCreated())
                    .andReturn().getResponse();
    
            final String location = response.getHeaderValue("location").toString();
    
            // Then
            mvc.perform(get(location)
                    .contentType(MediaType.APPLICATION_JSON))
                    .andExpect(status().isOk())
                    .andExpect(jsonPath("$._links.self.href").value(location));
    
        }
    }

标签: spring-bootjunit

解决方案


推荐阅读