使用 JsonUnit 的 JSON 單元測試斷言
1. 概述
在這篇短文中,我們將探索 JsonUnit 函式庫並使用它為 JSON 物件建立表達性斷言。我們將從一個簡單的範例開始,展示 JsonUnit 和 AssertJ 之間的平滑整合。
之後,我們將學習如何根據模板化String
驗證 JSON。這種方法提供了靈活性,並允許我們使用自訂佔位符將元素值與各種條件進行匹配或完全忽略特定的 JSON 路徑。
2. 入門
JsonUnit 專案包含幾個可以獨立導入的不同模組。 [json-unit-assertj](https://mvnrepository.com/artifact/net.javacrumbs.json-unit/json-unit-assertj)
模組是使用該庫的推薦方式,提供流暢的 API 並與 AssertJ 庫順利整合。
讓我們將此依賴項新增到pom.xml
中:
<dependency>
<groupId>net.javacrumbs.json-unit</groupId>
<artifactId>json-unit-assertj</artifactId>
<version>3.5.0</version>
<scope>test</scope>
</dependency>
該函式庫假設 JSON 反序列化器已在我們的類別路徑中,並自動嘗試使用它。目前,支援的整合有 Gson、org.json、Moshi 和 Jackson2。
我們現在可以使用靜態工廠方法assertThatJson()
來建立一個斷言物件。因此,我們將能夠使用 JsonUnit 的 Fluent API 來驗證測試的 JSON 是否是有效的 JSON 物件並驗證其鍵值對:
@Test
void whenWeVerifyAJsonObject_thenItContainsKeyValueEntries() {
String articleJson = """
{
"name": "A Guide to Spring Boot",
"tags": ["java", "spring boot", "backend"]
}
""";
assertThatJson(articleJson)
.isObject()
.containsEntry("name", "A Guide to Spring Boot")
.containsEntry("tags", List.of("java", "spring boot", "backend"));
}
JsonUnit 讓我們可以輕鬆瀏覽 JSON 對象,同時利用 AssertJ 強大的斷言進行驗證。例如,我們可以使用node()
等方法來導航 JSON,使用isArray()
來存取為斷言集合量身定制的 API:
assertThatJson(articleJson)
.isObject()
.containsEntry("name", "A Guide to Spring Boot")
.node("tags")
.isArray()
.containsExactlyInAnyOrder("java", "spring boot", "backend");
另一方面,我們可以以宣告的方式將測試物件與普通 JSON String
進行比較.
為此,我們只需將預期內容包裝在ExpectedNode
實例中,這可以使用函數JsonAssertion.json():
assertThatJson(articleJson)
.isObject()
.isEqualTo(json("""
{
"name": "A Guide to Spring Boot",
"tags": ["java", "spring boot", "backend"]
}
"""));
3. 支援的功能
該程式庫提供了許多功能,例如導航複雜的 JSON 路徑、忽略欄位或值以及針對自訂匹配器或正規表示式模式進行斷言。儘管我們不會討論所有功能,但我們將探討一些關鍵功能。
3.1.選項
JsonUnit 使我們能夠為每個斷言定義各種配置。我們可以在Option
枚舉中找到支援的功能,並透過when()
方法啟用它們。
讓我們啟用IGNORE_ARRAY_ORDER
和IGNORE_EXTRA_ARRAY_ITEMS
選項,以另一種方式驗證 JSON 是否以任意順序包含tags “java”
和“backend”
:
assertThatJson(articleJson)
.when(Option.IGNORING_ARRAY_ORDER)
.when(Option.IGNORING_EXTRA_ARRAY_ITEMS)
.node("tags")
.isEqualTo(json("""
["backend", "java"]
"""));
3.2.佔位符
當根據預期內容驗證 JSON 輸出時,該程式庫允許對預期結果進行範本化。例如,像${json-unit.any-string}
和${json-unit.ignore-element}
這樣的佔位符可以將文章的name
驗證為字串,同時忽略其tags
清單:
assertThatJson(articleJson)
.isEqualTo(json("""
{
"name": "${json-unit.any-string}",
"tags": "${json-unit.ignore-element}"
}
"""));
同樣,我們可以使用${json-unit.any-number}
、 ${json-unit.any-boolean}
、 ${json-unit.regex}
等佔位符,甚至可以建立針對特定用例的自訂佔位符。
3.3.忽略路徑
到目前為止,我們已經學習如何使用佔位符來忽略 JSON 物件的元素。但是,我們也可以利用whenIgnoringPaths()
方法來定義執行斷言時要忽略的 JSON 路徑:
assertThatJson(articleJson)
.whenIgnoringPaths("tags")
.isEqualTo(json("""
{
"name": "A Guide to Spring Boot",
"tags": [ "ignored", "tags" ]
}
"""));
}
正如我們所看到的,當我們使用whenIgnoringPaths(“tags”)
時,即使兩個JSON物件的tags
鍵值不同,斷言也會通過。
4. 結論
在本實踐教程中,我們討論了 JsonUnit 的基礎知識,並探索了它的 API,用於創建流暢的聲明性斷言,使 JSON 驗證變得簡單且富有表現力。
我們也學習如何透過將 JSON 內容與模板化String
進行比較來驗證它。當與其他庫功能(例如配置Option
、自訂佔位符和類型匹配器)配合使用時,該技術被證明特別強大。
與往常一樣,本文的程式碼可以在 GitHub 上取得。