您的位置:首页 > 编程语言 > Java开发

JSONAssert & Spring Boot Test

2017-10-12 00:00 501 查看

JSONAssert

本此测试用例正确的原始顺序为(需求见POST)

Body = [{"driver":"mvc","password":"mvc","url":"mvc","username":"mvc","port":"mvc"},{"driver":"com.mysql.jdbc.Driver","password":"password123456","url":"jdbc:mysql://DEVIP:PORT/DBNAME?characterEncoding=UTF-8","username":"username123456","port":"0"}]


元素里属性顺序可以变换.

String expected = "[{password:\"mvc\",driver:\"mvc\",url:\"mvc\",username:\"mvc\",port:\"mvc\"},{password:\"password123456\",driver:\"com.mysql.jdbc.Driver\",url:\"jdbc:mysql://DEVIP:PORT/DBNAME?characterEncoding=UTF-8\",username:\"username123456\",port:\"0\"}]";
JSONAssert.assertEquals(expected, result.getResponse().getContentAsString(), false);//pass
JSONAssert.assertEquals(expected, result.getResponse().getContentAsString(), true);//pass



strict模式:元素必须完整

非Strict模式,可以测试元素的部分属性

String expected="[{driver:\"com.mysql.jdbc.Driver\"},{password:\"mvc\"}]";
JSONAssert.assertEquals(expected,result.getResponse().getContentAsString(),true);//fail
JSONAssert.assertEquals(expected,result.getResponse().getContentAsString(),false);//pass



strict模式:元素之间顺序不能变换

非strict模式:元素之间顺序可以变换

String expected = "[{driver:\"mvc\",password:\"mvc\",url:\"mvc\",username:\"mvc\",port:\"mvc\"},{driver:\"com.mysql.jdbc.Driver\",password:\"password123456\",url:\"jdbc:mysql://DEVIP:PORT/DBNAME?characterEncoding=UTF-8\",username:\"username123456\",port:\"0\"}]";
JSONAssert.assertEquals(expected, result.getResponse().getContentAsString(), false);//pass
JSONAssert.assertEquals(expected, result.getResponse().getContentAsString(), true);//pass
expected = "[{driver:\"com.mysql.jdbc.Driver\",password:\"password123456\",url:\"jdbc:mysql://DEVIP:PORT/DBNAME?characterEncoding=UTF-8\",username:\"username123456\",port:\"0\"},{driver:\"mvc\",password:\"mvc\",url:\"mvc\",username:\"mvc\",port:\"mvc\"}]";
JSONAssert.assertEquals(expected, result.getResponse().getContentAsString(), false);//pass
JSONAssert.assertEquals(expected, result.getResponse().getContentAsString(), true);//fail

此列中我们可以看出,采用strict模式,测试将不能通过.

一般情况下,我们默认关闭strict模式,除非特殊情况下.

测试数组时:元素个数必须和原数组一样大小,只不过严格模式下不能调换元素顺序(当然元素里属性的顺序可以调换),非严格模式下可以调换元素顺序.

Spring Boot Test(注意这个是集成测试,但是里面得内容其实和测MVC层一样,后面我会用专门得博客来写mvc,service,dao层得测试,情况还都不太一样!)

GET

@GetMapping("/config")
public DataSourceConfig config() {
return testService.getConfig();
}

@
3ff0
Service
@RefreshScope
public class TestService {
@Value("${server.port}")
public String port;
@Value("${spring.datasource.driver-class-name}")
private String driver;
@Value("${spring.datasource.password}")
private String password;
@Value("${spring.datasource.url}")
private String url;
@Value("${spring.datasource.username}")
private String username;
public DataSourceConfig getConfig() {
return new DataSourceConfig(driver, password, url, username, port);
}
}

RestTemplate

@Data
@AllArgsConstructor
@NoArgsConstructor
public class DataSourceConfig implements Serializable {
private static final long serialVersionUID = 3178620210804628886L;
private String driver;
private String password;
private String url;
private String username;
private String port;
}

and you must add dependency in pom.xml

<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.1</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
</dependency>

DataSourceConfig result = restTemplate.getForObject("/config", DataSourceConfig.class);
String expected = "{\"driver\":\"com.mysql.jdbc.Driver\",\"password\":\"password123456\",\"url\":\"jdbc:mysql://DEVIP:PORT/DBNAME?characterEncoding=UTF-8\",\"username\":\"username123456\",\"port\":\"0\"}";
String actual = new Gson().toJson(result).replace("\\u003d","=");
JSONAssert.assertEquals(expected, actual, false);

下面是对gson的测试用例:

@Test
public void test() throws Exception {
DataSourceConfig result = new DataSourceConfig("com.mysql.jdbc.Driver", "password123456", "jdbc:mysql://DEVIP:PORT/DBNAME?characterEncoding=UTF-8", "username123456", "0");
String expected = "{\"driver\":\"com.mysql.jdbc.Driver\",\"password\":\"password123456\",\"url\":\"jdbc:mysql://DEVIP:PORT/DBNAME?characterEncoding=UTF-8\",\"username\":\"username123456\",\"port\":\"0\"}";
String unexpected = "{\"driver\":\"com.mysql.jdbc.Driver\",\"password\":\"password123456\",\"url\":\"jdbc:mysql://DEVIP:PORT/DBNAME?characterEncoding\\u003dUTF-8\",\"username\":\"username123456\",\"port\":\"0\"}";
assertNotEquals(expected, new Gson().toJson(result));
assertEquals(unexpected, new Gson().toJson(result));
}

MockMVC

下面是通过MockMVC来测试的方式:

MvcResult result = mvc.perform(get("/config"))
.andExpect(status().isOk())
.andDo(print())
.andReturn();
String expected = "{\"driver\":\"com.mysql.jdbc.Driver\",\"password\":\"password123456\",\"url\":\"jdbc:mysql://DEVIP:PORT/DBNAME?characterEncoding=UTF-8\",\"username\":\"username123456\",\"port\":\"0\"}";
JSONAssert.assertEquals(expected, result.getResponse().getContentAsString(), false);

POST

@PostMapping("/config")
public List<DataSourceConfig> dataSourceConfig(@RequestBody DataSourceConfig dataSource) {
List<DataSourceConfig> list = new ArrayList<>();
list.add(dataSource);
list.add(testService.getConfig());
return list;
}

RestTemplate

@Test
public void dataSourceConfigWithRestForPost() throws Exception {
DataSourceConfig dataSource = new DataSourceConfig("hs", "hs", "hs", "hs", "hs");
DataSourceConfig[] dataSourceConfigs = restTemplate.postForObject(URL, dataSource, DataSourceConfig[].class);
List<DataSourceConfig> actual = Arrays.asList(dataSourceConfigs);
List<DataSourceConfig> expected = Arrays.asList(dataSource, new DataSourceConfig("com.mysql.jdbc.Driver", "password123456", "jdbc:mysql://DEVIP:PORT/DBNAME?characterEncoding=UTF-8", "username123456", "0"));
assertThat(actual, is(expected));
assertThat(actual, hasSize(2));
assertThat(actual, hasItem(dataSource));
}

注意此处有两个坑:

不能用LIst来获取springmvc得到得list对象,应该采用数组来承接.

如果用数组不能正常反序列化请更换相应得高级版本自动解决.

MockMVC

DataSourceConfig dataSource = new DataSourceConfig("mvc", "mvc", "mvc", "mvc", "mvc");
RequestBuilder request = post(URL)
.content(new Gson().toJson(dataSource))
.accept(MediaType.APPLICATION_JSON_UTF8)
.contentType(MediaType.APPLICATION_JSON_UTF8);
MvcResult result = mvc.perform(request)
.andExpect(status().isOk())
.andDo(print())
.andReturn();
String expected = "[{driver:\"mvc\",password:\"mvc\",url:\"mvc\",username:\"mvc\",port:\"mvc\"},{driver:\"com.mysql.jdbc.Driver\",password:\"password123456\",url:\"jdbc:mysql://DEVIP:PORT/DBNAME?characterEncoding=UTF-8\",username:\"username123456\",port:\"0\"}]";
JSONAssert.assertEquals(expected, result.getResponse().getContentAsString(), false);//pass

PUT

@PutMapping("/config")
public voidsourceConfig(DataSourceConfig dataSource) {
dataSource.setPort(testService.getConfig().getPort());
dataSource.setUsername("Http PUT");
}

RestTemplate

@Test
public void testConfigWithRestForPut() throws Exception {
DataSourceConfig dataSource = new DataSourceConfig("hs", "hs", "hs", "hs", "hs");
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
HttpEntity<DataSourceConfig> entity = new HttpEntity<DataSourceConfig>(dataSource, headers);
HttpStatus statusCode = restTemplate.exchange(URL, HttpMethod.PUT, entity, Object.class).getStatusCode();
assertTrue(statusCode.is2xxSuccessful());
}

MockMVC

@Test
@Test
public void testConfigWithMVCForPut() throws Exception {
DataSourceConfig dataSource = new DataSourceConfig("hs", "hs", "hs", "hs", "hs");
RequestBuilder request = put(URL)
.content(new Gson().toJson(dataSource))
.contentType(MediaType.APPLICATION_JSON_UTF8);
mvc.perform(request)
.andExpect(status().is2xxSuccessful());
}

DELETE

@DeleteMapping("/config")
public void deleteDataSource(@RequestBody DataSourceConfig dataSource, @RequestParam String id) {
testService.getConfig();
System.out.println(dataSource + "->" + id);
}

RestTemplate

@Test
public void testConfigWithRestForDelete() throws Exception {
DataSourceConfig dataSource = new DataSourceConfig("hs", "hs", "hs", "hs", "hs");
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
HttpEntity<DataSourceConfig> entity = new HttpEntity<DataSourceConfig>(dataSource, headers);
Map<String, String> params = new HashMap<>();
params.put("id", "1");
System.out.println(restTemplate.exchange(URL, HttpMethod.DELETE, entity, Object.class,params).getBody());
HttpStatus status = restTemplate.exchange(URL+"?id=\"1\"", HttpMethod.DELETE, entity, Object.class).getStatusCode();
assertTrue(status.is2xxSuccessful());
}

MockMVC

@Test
public void testConfigWithMVCForDelete() throws Exception {
DataSourceConfig dataSource = new DataSourceConfig("mvc", "mvc", "mvc", "mvc", "mvc");
RequestBuilder request = delete(URL)
.content(new Gson().toJson(dataSource))
.contentType(MediaType.APPLICATION_JSON_UTF8)
.param("id","\"2\"");
mvc.perform(request)
.andExpect(status().is2xxSuccessful());
}

这里明显留了一个问题,采用restful形式得时候不知道怎么传递
?param=value
这种形式得参数.请会得朋友告知.

接上,上次遗留的问题今天解决了.下面继续补充一点知识

在测试端获得端口号采用这种形式,别写错,要不得到的值就是0.

@LocalServerPort
private int port;


?param=value
这种形式比较麻烦,祥见下面代码:

@Test
public void deleteDocker() throws Exception {
HttpHeaders headers = new HttpHeaders();
headers.set("Accept", MediaType.APPLICATION_JSON_UTF8_VALUE);
HttpEntity entity = new HttpEntity(headers);
restTemplate.exchange(UriComponentsBuilder.fromHttpUrl("http://localhost:" + port + PATH)
.queryParam("name", "hs")
.queryParam("port", 23).build().encode().toUri(), HttpMethod.DELETE, entity, Docker.class);
}


public <T> T postForObject(String url, Object request, Class<T> responseType, Object... urlVariables) throws RestClientException
最后一个参数的代码:

@Test
public void setDocker() throws Exception {
List<Docker> dockerList = Arrays.asList(new Docker("hs", "22"), new Docker("ys", "21"), new Docker("zs", "20"));
Docker[] dockers = restTemplate.postForObject("/dockers/{name}/docker/{port}", dockerList, Docker[].class, "ys", 20);
restTemplate.postForObject("/dockers/{name}/docker/{port}", dockerList, Docker[].class, "ys", 20);
logger.info(Arrays.toString(dockers));
assertThat(Arrays.asList(dockers), is(dockerList));
}

说白了,这个就是如其名,解决这种
/dockers/{name}/docker/{port}
参数传递的问题.至此,3种参数传递的问题都解决了.

最后再补充一个query string相同的列子

@Test
public void receiveStringList() throws Exception {
String[] strings = restTemplate.getForObject(UriComponentsBuilder.fromHttpUrl("http://localhost:"+port+"/strList")
.queryParam("strList","hs")
.queryParam("strList","ys")
.queryParam("strList","ws")
.queryParam("strList","zs").toUriString(), String[].class);
assertThat(Arrays.asList(strings), is(Arrays.asList("hs", "ys", "ws", "zs")));
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  JSON Java springboottest