我创建了一个Spring boot CRUD的小型解决方案,并遇到了问题测试 @PutMapping 预计将检索更新的Country对象,但返回值包括所有已保存国家/地区的列表
国家实体
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
import lombok.Data;
@SuppressWarnings("serial")
@Data
@Entity
//@NoArgsConstructor
@SequenceGenerator(name = "SEQ_COUNTRY", allocationSize = 1, initialValue = 1)
public class Country implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_COUNTRY")
private Long id;
@NotBlank
@Column(unique = true)
private String name;
@Pattern(regexp = "^\\+(?:[0-9]){1,3}")
private String countryCode;
public Country() {
}
public Country(String name, String countryCode) {
this.name = name;
this.countryCode = countryCode;
}
public Country(Long id, String name, String countryCode) {
this.id = id;
this.name = name;
this.countryCode = countryCode;
}
}
import java.net.URI;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import edu.ndsi.microservices.country.domain.Country;
import edu.ndsi.microservices.country.exception.RecordNotFoundException;
import edu.ndsi.microservices.country.exception.UniqueConstraintException;
import edu.ndsi.microservices.country.exception.ValidateRecordException;
import edu.ndsi.microservices.country.service.CountryService;
import lombok.extern.slf4j.Slf4j;
@RestController
@Slf4j
public class CountryController {
@Autowired
private CountryService countryService;
@Autowired
private Environment env;
@GetMapping("/countries")
public List<Country> retrieveAllCountries() {
log.info("\n Country Instance Port: {}", env.getProperty("server.port"));
return countryService.findAllCountries();
}
@GetMapping("/countries/{id}")
public Country retrieveCountryById(@PathVariable Long id) {
log.info("\n Country retrieveCountryById: {}", env.getProperty("server.port"));
Country country = countryService.getCountryById(id);
if (null == country) {
throw new RecordNotFoundException(" No country with this Id", id);
}
return country;
}
@PostMapping("/countries")
public ResponseEntity<Country> save(@RequestBody Country newCountry)
throws UniqueConstraintException, ValidateRecordException {
log.info("\n Country Instance Port: {}", env.getProperty("server.port"));
log.info("\n newCountry {}", newCountry);
if (newCountry.getId() != null)
throw new ValidateRecordException("Key should not exist in Request. Remove 'id' from request body");
if (countryService.nameExists(newCountry.getName()))
throw new UniqueConstraintException("Country already exists with name", newCountry.getName());
Country savedCountry = countryService.saveCountry(newCountry);
URI location = ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}")
.buildAndExpand(savedCountry.getId()).toUri();
return ResponseEntity.created(location).body(savedCountry);
}
@PutMapping("/countries")
public ResponseEntity<Country> update(@RequestBody Country country)
throws ValidateRecordException, UniqueConstraintException {
log.info("\n Country Instance Port: {}", env.getProperty("server.port"));
log.info("\n newCountry {}", country);
if (null == country.getId() || country.getId() < 1 )
throw new ValidateRecordException("Key should exist in request body and equivalent to path.");
Country countryExisting = countryService.getCountryById(country.getId());
if (countryExisting.equals(country))
return ResponseEntity.status(HttpStatus.NOT_MODIFIED).body(country);
Country savedCountry = countryService.saveCountry(country);
return ResponseEntity.status(HttpStatus.OK).body(savedCountry);
}
}
测试部分
import static org.junit.Assert.assertEquals;
import java.util.Arrays;
import org.json.JSONException;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.skyscreamer.jsonassert.JSONAssert;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringRunner;
import edu.ndsi.microservices.country.domain.Country;
import lombok.extern.slf4j.Slf4j;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = { "eureka.client.enabled=false" })
@Slf4j
public class CountryControllerTest {
@LocalServerPort
private int localPort;
private static String url;
private static HttpHeaders headers = new HttpHeaders();
@Before
public void setup() {
// set initials
url = String.format("%s%s%s", "http://localhost:", localPort, "/countries/");
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
}
@Test
public void test_update_return_updatedCountry() throws JSONException {
String expected = "{\"id\":30002,\"name\":\"UK\",\"countryCode\":\"+44\"}";
HttpEntity<Country> entity = new HttpEntity<>(new Country(30002l, "Norway", "+47"));
TestRestTemplate restTemplate = new TestRestTemplate();
log.info("\n url : {} \n entity: {} \n restTemplate: {}", url, entity, restTemplate);
restTemplate.put(url, entity);
ResponseEntity<String> response
= restTemplate.getForEntity(url ,
String.class);
log.info("\n test_update_return_updatedCountry : {} \n got: {}", expected, response);
assertEquals(HttpStatus.OK, response.getStatusCode());
JSONAssert.assertEquals(expected, response.getBody(), false);
}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
http://maven.apache.org/xsd/maven-4.0.0.xsd“> 4.0.0 org.springframework.boot 弹簧启动启动器父母 2.2.0.BUILD-SNAPSHOT 教育微服务 设置 0.0.1-快照 战争 设置 Spring Boot配置服务器
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.BUILD-SNAPSHOT</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- Start Caching -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId> <!--Starter for using Spring Framework's caching support -->
</dependency>
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId> <!-- JSR-107 API-->
</dependency>
<dependency>
<groupId>javax.cache</groupId>
<artifactId>cache-api</artifactId>
</dependency>
<!-- End Caching -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</pluginRepository>
</pluginRepositories>