Java 如何为json模型构建测试数据生成器
我有一个微服务/应用程序,它接受JSON并转换为java POJO,然后在该应用程序中进一步处理。假设结构是:Java 如何为json模型构建测试数据生成器,java,json,Java,Json,我有一个微服务/应用程序,它接受JSON并转换为java POJO,然后在该应用程序中进一步处理。假设结构是: { "header": { "msgTs": "2020-02-20T11:00:00" } "hazmat": { "name": "a" } // some other properties } public class Hazmat { private String hazmatName
{
"header": {
"msgTs": "2020-02-20T11:00:00"
}
"hazmat": {
"name": "a"
}
// some other properties
}
public class Hazmat {
private String hazmatName;
}
public class POJO {
private Header header;
private Hazmat hazmet;
}
在这里,“危险品”可能存在或不存在。对于所有测试数据,header和msgTs的值并不重要。因此,我们可以硬编码值
现在要测试它,我想创建一个测试数据生成器。建筑商将如下所示:
public class PojoBulider {
private String hazmatName;
public PojoBuilder withHamatName(String hazmatName) { this.hazmatname = hazmatName; return this; }
public String build() {
// generate test data from the captured inputs eg "hazmatName".
}
}
为了生成测试数据,用户输入/特征文件列值将与一些选定的属性(例如hazmatName)一起使用。其余的可以硬编码
现在的问题是,我们如何硬编码固定值,如msgTs?我可以有一个json模板:
{
"header": {
"msgTs": "2020-02-20T11:00:00"
}
"hazmat": {
"name": "%%hazmatName%%"
}
}
{
"header": {
"msgTs": "2020-02-20T11:00:00"
}
"toy": {
"name": "%%toyName%%"
}
}
然后有:
public void build() {
String templateJson; // load from file;
templateJson = templateJson.replaceAll("%%hazmatName%%", hazmatName);
return templateJson;
}
问题是JSON可以有存在和不存在的属性。因此,我不能有多个可能值不同的templateJson,即一个templateJson:
{
"header": {
"msgTs": "2020-02-20T11:00:00"
}
"hazmat": {
"name": "%%hazmatName%%"
}
}
另一个模板json:
{
"header": {
"msgTs": "2020-02-20T11:00:00"
}
"hazmat": {
"name": "%%hazmatName%%"
}
}
{
"header": {
"msgTs": "2020-02-20T11:00:00"
}
"toy": {
"name": "%%toyName%%"
}
}
我不能将一个json模板设置为:
{
"header": {
"msgTs": "2020-02-20T11:00:00"
}
"toy": {
"name": "%%toyName%%"
}
"hazmat": {
"name": "%%hazmatName%%"
}
}
因为测试数据不会同时包含“玩具”和“危险品”部分
所以我被卡住了。我可能有多个json模板,比如hazmat的一个,hazmat.json:
"hazmat": {
"name": "%%hazmatName%%"
}
另一个是玩具:
"toy": {
"name": "%%toyName%%"
}
并将它们组合为:
public String build() {
if (hazmatName != null) {
// load hazmatJson
// append to templateJson
}
if (toyName != null) {
// load toyJson
// append to templateJson
}
return templateJson;
}
我想改用POJO:
public String build() [
Pojo pojo = new Pojo();
Hazmat hazmat = new Hazmat();
hazmat.setHazmatName(this.hazmatName);
pojo.setHazmat(hazmat);
return new ObjectMapper().writeValueAsString(pojo);
}
但问题是如何填充所有json都不会更改的标头等值。我可以有另一个json:
{
"header": { "msgTs": "..." } }
然后使用ObjectMapper加载来加载它:
public String build() {
Header header = new ObjectMapper().load("header.json");
pojo.setHeader(header);
}
是否有一种完全基于java的方法,而不使用任何json文件(即header.json、toy.json、hazmat.json)?在这种情况下,人们通常如何生成测试数据 当您评论说您更喜欢修改字段而不是基于键的映射时,我写下了这个答案,解释了在该约束下我将做什么(并不是说这是最好的解决方案,因为我将使用恒定键和映射) 仍然假设您最终想要生成一个类似json的
字符串
作为测试候选者的输入,我将创建一个将自身打印为json格式的类。请注意,我只测试了对象数组,而不是基本数组!列表、贴图和集合类型也不包括在内,但如果愿意,您可以自己添加它们
import java.lang.reflect.Field;
导入java.lang.reflect.InvocationTargetException;
导入java.util.ArrayList;
导入java.util.array;
导入java.util.List;
公共抽象类JSON{
公共静态最终对象未定义=新对象();
公共字符串tojsonthrowrite(){
试一试{
返回到jsonString();
}捕获(可丢弃的t){
抛出新的RuntimeException(“我找到了它。我可以保留它吗?:)”,t);
}
}
公共字符串toJsonString()抛出NoSuchMethodException、SecurityException、,
IllegalArgumentException、IllegalAccessException、InvocationTargetException{
StringBuilder sb=新的StringBuilder();
布尔值优先=真;
for(字段:getAllDeclaredFields()){
字符串名称=field.getName();
//这可以防止无休止的递归。
如果(name.startsWith(“本”)){
继续;
}
类fieldType=field.getType();
if(fieldType.isPrimitive()){
//第一个字段前不需要有“,”号。
如果(第一){
第一个=假;
}否则{
sb.追加(“,\n”);
}
//这很麻烦,但我没有更干净的解决方案。
某人追加(姓名)。追加(“:”);
开关(fieldType.getTypeName()){
案例“int”:
sb.append(field.getInt(this));
打破
案例“long”:
sb.append(field.getLong(this));
打破
案例“布尔”:
sb.append(field.getBoolean(this));
打破
案例“char”:
sb.append(“'”+field.getChar(this)+“'”);
打破
“双重”情况:
sb.append(field.getDouble(this));
打破
案例“浮动”:
sb.append(field.getFloat(this));
打破
大小写“字节”:
sb.append(field.getByte(this));
打破
案例“短”:
sb.append(field.getShort(this));
打破
}
}否则{
字符串值=valueToString(field.get(this));
if(值!=null){
//第一个字段前不需要有“,”号。
如果(第一){
第一个=假;
}否则{
sb.追加(“,\n”);
}
附加(名称)。附加(“:”)。附加(值);
}
}
}
返回“{\n”+缩进(sb.toString())+”\n}”;
}
公共字符串值ToString(对象值)抛出NoSuchMethodException、SecurityException、,
IllegalArgumentException、IllegalAccessException、InvocationTargetException{
如果(值==null){
返回“null”;
}else if(值==未定义){
返回null;
}else if(JSON的值实例){
JSON childJson=(JSON)值;
返回childJson.toJsonString();
}else if(字符串的值实例){
返回“\”+值+“\”;
}else if(字符的值实例){
返回“'”+值+“'”;
}else if(value.getClass().isArray()){
对象[]数组=(对象[])值;
StringBuilder sb=新的StringBuilder();
布尔值优先=真;
for(对象o:array){
如果(第一)