Spring Boot模拟REST API集成测试:在JSON响应中查找空值

Spring Boot模拟REST API集成测试:在JSON响应中查找空值,json,spring,spring-mvc,jhipster,Json,Spring,Spring Mvc,Jhipster,作为Spring Boot应用程序的一部分,我正在尝试调整集成测试,以确保返回的JSON对象包含特定属性的null: import static org.springframework.test.web.servlet.ResultActions.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; .andExpect(jsonPath("$.selectedChannels

作为Spring Boot应用程序的一部分,我正在尝试调整集成测试,以确保返回的JSON对象包含特定属性的null:

import static org.springframework.test.web.servlet.ResultActions.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

.andExpect(jsonPath("$.selectedChannels[0].channelValue")
    .doesNotExist())
这似乎不起作用。答复如下:

{
    "selectedChannels": [{
        "name": "test channel",
        "channelValue": null
    }]
}
java.lang.AssertionError: Expected no value at JSON path "$.selectedChannels[0].channelValue" but found: [null]
我会得到一个回应:

{
    "selectedChannels": [{
        "name": "test channel",
        "channelValue": null
    }]
}
java.lang.AssertionError: Expected no value at JSON path "$.selectedChannels[0].channelValue" but found: [null]

我想“doesNotExist”调用是为了确保密钥不存在。我尝试使用“value”和空值,但这只是抛出一个NPE。如何成功执行此断言?

JSON路径匹配器
doesNotExist()
用于断言不存在密钥。例如,存在键
channelValue
,因此断言失败。另请参见官方Javadocs(),了解JsonPathResultMatchers
doesNotExist()

根据响应内容计算JSON路径表达式,并断言给定路径上不存在值

对于提供的响应,您需要检查响应是否包含键的null值
channelValue

resultActions.andExpect(jsonPath("$.selectedChannels[0].channelValue").value(nullValue());

确保为Hamcrest nullValue()matcher添加静态导入:
import static org.Hamcrest.Matchers.nullValue

JSON路径匹配器
doesNotExist()
用于断言不存在密钥。例如,存在键
channelValue
,因此断言失败。另请参见官方Javadocs(),了解JsonPathResultMatchers
doesNotExist()

根据响应内容计算JSON路径表达式,并断言给定路径上不存在值

对于提供的响应,您需要检查响应是否包含键的null值
channelValue

resultActions.andExpect(jsonPath("$.selectedChannels[0].channelValue").value(nullValue());

确保为Hamcrest nullValue()matcher添加静态导入:
import static org.Hamcrest.Matchers.nullValue

我认为可能存在一些错误,导致Spring Framework(目前的Spring Boot版本为1.5.4)将null值呈现为net.minidev.json.JSONArray,其中一个值为null。所以
“channelValue”:null
被呈现为
“channelValue”:[null]
。这将阻止nullValue匹配器工作

目前,我能找到的解决这个问题的唯一方法是实现并使用我自己的Matcher。使用空值匹配器作为模板,我有以下几点:

import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import net.minidev.json.JSONArray;

/**
 * Matcher that can be used to detect if a value is null or refers to an empty list,
 * or a list that contains a single null value. 
 *
 * @param <T>
 */
public class IsNullOrEmpty<T> extends BaseMatcher<T> {

    @Override
    public boolean matches(Object item) {
        System.out.println(item.getClass().getPackage());
        if(item instanceof JSONArray) {
            JSONArray arr = ((JSONArray)item);
            return arr==null || arr.size()==0 || (arr.size()==1 && arr.get(0)==null);
        }
        return item==null;
    }

    @Override
    public void describeTo(Description description) {
        description.appendText("null or list of null");
    }

    /**
     * Detect if the value is null or contains an empty array, or an array of a single element
     * of null
     * @return
     */
    public static Matcher<Object> isNullOrEmpty() {
        return new IsNullOrEmpty<>();
    }

}
import org.hamcrest.BaseMatcher;
导入org.hamcrest.Description;
导入org.hamcrest.Matcher;
导入net.minidev.json.JSONArray;
/**
*匹配器,可用于检测值是否为null或是否引用空列表,
*或包含单个空值的列表。
*
*@param
*/
公共类IsNullOrEmpty扩展BaseMatcher{
@凌驾
公共布尔匹配(对象项){
System.out.println(item.getClass().getPackage());
if(JSONArray的项目实例){
JSONArray arr=((JSONArray)项);
返回arr==null | | arr.size()==0 | |(arr.size()==1&&arr.get(0)==null);
}
返回项==null;
}
@凌驾
公共无效说明(说明){
说明.附录文本(“空或空列表”);
}
/**
*检测值是否为null或包含空数组或单个元素的数组
*空的
*@返回
*/
公共静态匹配器isNullOrEmpty(){
返回新的IsNullOrEmpty();
}
}

我认为可能存在一些错误,导致Spring Framework(目前的Spring Boot版本为1.5.4)将null值呈现为net.minidev.json.JSONArray,其中一个值为null。所以
“channelValue”:null
被呈现为
“channelValue”:[null]
。这将阻止nullValue匹配器工作

目前,我能找到的解决这个问题的唯一方法是实现并使用我自己的Matcher。使用空值匹配器作为模板,我有以下几点:

import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import net.minidev.json.JSONArray;

/**
 * Matcher that can be used to detect if a value is null or refers to an empty list,
 * or a list that contains a single null value. 
 *
 * @param <T>
 */
public class IsNullOrEmpty<T> extends BaseMatcher<T> {

    @Override
    public boolean matches(Object item) {
        System.out.println(item.getClass().getPackage());
        if(item instanceof JSONArray) {
            JSONArray arr = ((JSONArray)item);
            return arr==null || arr.size()==0 || (arr.size()==1 && arr.get(0)==null);
        }
        return item==null;
    }

    @Override
    public void describeTo(Description description) {
        description.appendText("null or list of null");
    }

    /**
     * Detect if the value is null or contains an empty array, or an array of a single element
     * of null
     * @return
     */
    public static Matcher<Object> isNullOrEmpty() {
        return new IsNullOrEmpty<>();
    }

}
import org.hamcrest.BaseMatcher;
导入org.hamcrest.Description;
导入org.hamcrest.Matcher;
导入net.minidev.json.JSONArray;
/**
*匹配器,可用于检测值是否为null或是否引用空列表,
*或包含单个空值的列表。
*
*@param
*/
公共类IsNullOrEmpty扩展BaseMatcher{
@凌驾
公共布尔匹配(对象项){
System.out.println(item.getClass().getPackage());
if(JSONArray的项目实例){
JSONArray arr=((JSONArray)项);
返回arr==null | | arr.size()==0 | |(arr.size()==1&&arr.get(0)==null);
}
返回项==null;
}
@凌驾
公共无效说明(说明){
说明.附录文本(“空或空列表”);
}
/**
*检测值是否为null或包含空数组或单个元素的数组
*空的
*@返回
*/
公共静态匹配器isNullOrEmpty(){
返回新的IsNullOrEmpty();
}
}

我在我引用的任何库中都没有看到
nullValue
的静态方法。你能告诉我它的正确位置吗?它是一个Hamcrest matcher,应该已经是你的JHipster应用程序的一部分了。使用
导入静态org.hamcrest.Matchers.nullValue导入啊,那个特定的匹配器不起作用:
org.hamcrest.core.IsNull.nullValue()
返回响应:Expected:null但是:was。Spring的JsonPathResultMatchers出于某种原因正在将null强制转换为null列表。我在我引用的任何库中都没有看到关于
nullValue
的静态方法。你能告诉我它的正确位置吗?它是一个Hamcrest matcher,应该已经是你的JHipster应用程序的一部分了。使用
导入静态org.hamcrest.Matchers.nullValue导入啊,那个特定的匹配器不起作用:
org.hamcrest.core.IsNull.nullValue()
返回响应:Expected:null但是:was。斯普林的Jso