spring-boot - 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));
}
}
解决方案
推荐阅读
- c# - Mongodb Bson 类型为 Json
- javascript - 基于 Javascript 的 UWP 项目可以访问 service worker 吗?
- gnuplot - 如何将时间导数(点)放在 Gnuplot 5.2 Patchlevel 6a 中的变量 x 之上?
- r - 如何在 R 中格式化时间
- powershell - 获取参数的选定值以为 Powershell 中的下一个参数提供值
- node.js - 无法从 mongodb 更改流“更改”事件中删除侦听器
- php - 如何在 Symfony 4 的一个控制器中将参数从函数传递到函数?
- python - 如何在 wx.ComboBox 弹出窗口的悬停(或每个)项目的右侧添加“删除按钮”
- sql - 如果 where 子句返回零行,则选择虚拟值
- firebase - 写入子集合 Firestore 规则的问题