Agent Skills by ALSEL
Anthropic Claudeその他⭐ リポ 0品質スコア 50/100

unit-test-json-serialization

JacksonおよびSpring Bootの`@JsonTest`を使ったJSONシリアライズ/デシリアライズのユニットテストパターンを提供します。JSONマッピング、カスタムシリアライザー、日付フォーマット、ポリモーフィック型の検証に対応しています。JSONシリアライズのテスト作成やカスタムシリアライザーの検証が必要な際に活用してください。

description の原文を見る

Provides patterns for unit testing JSON serialization/deserialization with Jackson and `@JsonTest`. Validates JSON mapping, custom serializers, date formats, and polymorphic types. Use when testing JSON serialization, validating custom serializers, or writing JSON unit tests in Spring Boot applications.

SKILL.md 本文

@JsonTest を使用した JSON シリアライゼーション のユニットテスト

概要

Spring の @JsonTest と Jackson を使用した JSON シリアライゼーション とデシリアライゼーション のユニットテストパターンを提供します。POJO マッピング、カスタムシリアライザー、フィールド名マッピング、ネストされたオブジェクト、日付/時刻フォーマット、ポリモーフィック型をカバーしています。

使用時機

  • DTO の JSON シリアライゼーション/デシリアライゼーション のテスト
  • カスタム Jackson シリアライザー/デシリアライザーの検証
  • @JsonProperty@JsonIgnore、フィールド名マッピングの検証
  • 日付/時刻フォーマットの処理テスト (LocalDateTime, Date)
  • null ハンドリングと欠落フィールドのテスト
  • ポリモーフィック型デシリアライゼーション のテスト

手順

  1. テストクラスを @JsonTest でアノテーション → JacksonTester の自動構成を有効化
  2. 対象型に JacksonTester をオートワイア → タイプセーフな JSON アサーション を提供
  3. シリアライゼーション のテストjson.write(object) を呼び出し、extractingJsonPath* で JSON パスをアサート
  4. デシリアライゼーション のテストjson.parse(json) または json.parseObject(json) を呼び出し、オブジェクトの状態をアサート
  5. ラウンドトリップを検証 → シリアライズ してからデシリアライズ し、データが同じであることを確認 (オブジェクトが適切に比較可能な場合)
  6. エッジケースをテスト → null 値、欠落フィールド、空のコレクション、無効な JSON
  7. 検証チェックポイントを追加: 各アサーション 後、誤ったデータで有意義にテストが失敗することを確認

Maven セットアップ

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-json</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-test</artifactId>
  <scope>test</scope>
</dependency>

Gradle セットアップ

dependencies {
  implementation("org.springframework.boot:spring-boot-starter-json")
  testImplementation("org.springframework.boot:spring-boot-starter-test")
}

基本的なシリアライゼーション とデシリアライゼーション

@JsonTest
class UserDtoJsonTest {

  @Autowired
  private JacksonTester<UserDto> json;

  @Test
  void shouldSerializeUserToJson() throws Exception {
    UserDto user = new UserDto(1L, "Alice", "alice@example.com", 25);
    JsonContent<UserDto> result = json.write(user);

    result
      .extractingJsonPathNumberValue("$.id").isEqualTo(1)
      .extractingJsonPathStringValue("$.name").isEqualTo("Alice")
      .extractingJsonPathStringValue("$.email").isEqualTo("alice@example.com")
      .extractingJsonPathNumberValue("$.age").isEqualTo(25);
  }

  @Test
  void shouldDeserializeJsonToUser() throws Exception {
    String json_content = "{\"id\":1,\"name\":\"Alice\",\"email\":\"alice@example.com\",\"age\":25}";
    UserDto user = json.parse(json_content).getObject();

    assertThat(user.getId()).isEqualTo(1L);
    assertThat(user.getName()).isEqualTo("Alice");
    assertThat(user.getEmail()).isEqualTo("alice@example.com");
    assertThat(user.getAge()).isEqualTo(25);
  }

  @Test
  void shouldHandleNullFields() throws Exception {
    String json_content = "{\"id\":1,\"name\":null,\"email\":\"alice@example.com\"}";
    UserDto user = json.parse(json_content).getObject();
    assertThat(user.getName()).isNull();
  }
}

カスタム JSON プロパティ

public class Order {
  @JsonProperty("order_id")
  private Long id;

  @JsonProperty("total_amount")
  private BigDecimal amount;

  @JsonIgnore
  private String internalNote;
}

@JsonTest
class OrderJsonTest {

  @Autowired
  private JacksonTester<Order> json;

  @Test
  void shouldMapJsonPropertyNames() throws Exception {
    String json_content = "{\"order_id\":123,\"total_amount\":99.99}";
    Order order = json.parse(json_content).getObject();
    assertThat(order.getId()).isEqualTo(123L);
    assertThat(order.getAmount()).isEqualByComparingTo(new BigDecimal("99.99"));
  }

  @Test
  void shouldIgnoreJsonIgnoreFields() throws Exception {
    Order order = new Order(123L, new BigDecimal("99.99"));
    order.setInternalNote("Secret");
    assertThat(json.write(order).json).doesNotContain("internalNote");
  }
}

ネストされたオブジェクト

public class Product {
  private Long id;
  private String name;
  private Category category;
  private List<Review> reviews;
}

@JsonTest
class ProductJsonTest {

  @Autowired
  private JacksonTester<Product> json;

  @Test
  void shouldSerializeNestedObjects() throws Exception {
    Product product = new Product(1L, "Laptop", new Category(1L, "Electronics"));
    JsonContent<Product> result = json.write(product);

    result
      .extractingJsonPathNumberValue("$.category.id").isEqualTo(1)
      .extractingJsonPathStringValue("$.category.name").isEqualTo("Electronics");
  }

  @Test
  void shouldDeserializeNestedObjects() throws Exception {
    String json_content = "{\"id\":1,\"name\":\"Laptop\",\"category\":{\"id\":1,\"name\":\"Electronics\"}}";
    Product product = json.parse(json_content).getObject();
    assertThat(product.getCategory().getName()).isEqualTo("Electronics");
  }

  @Test
  void shouldHandleListOfNestedObjects() throws Exception {
    String json_content = "{\"id\":1,\"reviews\":[{\"rating\":5},{\"rating\":4}]}";
    Product product = json.parse(json_content).getObject();
    assertThat(product.getReviews()).hasSize(2);
  }
}

日付/時刻フォーマット

@JsonTest
class DateTimeJsonTest {

  @Autowired
  private JacksonTester<Event> json;

  @Test
  void shouldFormatDateTimeCorrectly() throws Exception {
    LocalDateTime dt = LocalDateTime.of(2024, 1, 15, 10, 30, 0);
    json.write(new Event("Conference", dt))
      .extractingJsonPathStringValue("$.scheduledAt").isEqualTo("2024-01-15T10:30:00");
  }
}

カスタムシリアライザー

public class CustomMoneySerializer extends JsonSerializer<BigDecimal> {
  @Override
  public void serialize(BigDecimal value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
    gen.writeString(value == null ? null : String.format("$%.2f", value));
  }
}

@JsonTest
class CustomSerializerTest {

  @Autowired
  private JacksonTester<Price> json;

  @Test
  void shouldUseCustomSerializer() throws Exception {
    json.write(new Price(new BigDecimal("99.99")))
      .extractingJsonPathStringValue("$.amount").isEqualTo("$99.99");
  }
}

ポリモーフィックデシリアライゼーション

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
@JsonSubTypes({
  @JsonSubTypes.Type(value = CreditCard.class, name = "credit_card"),
  @JsonSubTypes.Type(value = PayPal.class, name = "paypal")
})
public abstract class PaymentMethod { }

@JsonTest
class PolymorphicJsonTest {

  @Autowired
  private JacksonTester<PaymentMethod> json;

  @Test
  void shouldDeserializeCreditCard() throws Exception {
    String json_content = "{\"type\":\"credit_card\",\"id\":\"card123\"}";
    assertThat(json.parse(json_content).getObject()).isInstanceOf(CreditCard.class);
  }

  @Test
  void shouldDeserializePayPal() throws Exception {
    String json_content = "{\"type\":\"paypal\",\"id\":\"pp123\"}";
    assertThat(json.parse(json_content).getObject()).isInstanceOf(PayPal.class);
  }
}

ベストプラクティス

  • シリアライゼーション とデシリアライゼーション の両方をテストして完全なカバレッジを確保
  • JSON 全体を比較するのではなく、JSON パスを個別に検証
  • null ハンドリングを明示的にテスト — null フィールドは @JsonInclude に応じて含まれたり除外されたりする場合があります
  • extractingJsonPath* メソッドを使用してフィールドアサーション を精密に実行
  • ラウンドトリップをテスト: オブジェクトをシリアライズ し、JSON をデシリアライズ し、結果が一致することを確認
  • エッジケースを検証: 空の文字列、空のコレクション、深くネストされた構造
  • 関連するアサーション を単一のテストにグループ化して明確性を向上

制約と警告

  • @JsonTest 限定的なコンテキスト読み込み: JSON 関連のビーンのみ。完全な Spring コンテキストには @SpringBootTest を使用してください
  • Jackson バージョン: アノテーションバージョンが使用中の Jackson バージョンと一致していることを確認
  • 日付フォーマット: ISO-8601 がデフォルト。カスタムパターンには @JsonFormat を使用
  • Null ハンドリング: @JsonInclude(Include.NON_NULL) を使用して null をシリアライゼーション から除外
  • 循環参照: 無限ループを防ぐために @JsonManagedReference/@JsonBackReference を使用
  • イミュータブルオブジェクト: コンストラクタベースのデシリアライゼーション に @JsonCreator + @JsonProperty を使用
  • ポリモーフィック型: @JsonTypeInfo は デシリアライゼーション が機能するためにサブタイプを正しく識別する必要があります

デバッグワークフロー

JSON テストが失敗した場合は、このワークフローに従ってください:

失敗の兆候一般的な原因確認方法
JsonPath アサーション 失敗フィールド名の不一致@JsonProperty のスペルが JSON キーと一致しているか確認
Null が期待されたが値を取得@JsonInclude(NON_NULL) 設定済みフィールド/クラスのアノテーション を確認
デシリアライゼーション で間違った型を返す@JsonTypeInfo 欠落JSON に型情報プロパティを追加するか、サブタイプマッピングを設定
日付フォーマット不一致フォーマット文字列が不正@JsonFormat(pattern=...) が期待される文字列と一致していることを確認
出力でフィールドが欠落@JsonIgnore または transient 修飾子フィールドに @JsonIgnore または transient キーワードがあるか確認
ネストされたオブジェクトが null内側の JSON が欠落または不正形式解析された JSON をログ出力。内側の構造が POJO と一致することを確認
JsonParseExceptionJSON 文字列が不正形式JSON 構文を検証。エスケープ されていない文字を確認

修正後の検証チェックポイント: テストを再実行 — パスしたら、対比するテストを記述してください (例: null ハンドリングを修正したら、非 null 値のテストを追加して回帰を防止)。

リファレンス

ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ

詳細情報

作者
giuseppe-trisciuoglio
リポジトリ
giuseppe-trisciuoglio/developer-kit
ライセンス
MIT
最終更新
不明

Source: https://github.com/giuseppe-trisciuoglio/developer-kit / ライセンス: MIT

関連スキル

汎用その他⭐ リポ 1,982

superfluid

Superfluidプロトコルおよびそのエコシステムに関するナレッジベースです。Superfluidについて情報を検索する際は、ウェブ検索の前にこちらを参照してください。対応キーワード:Superfluid、CFA、GDA、Super App、Super Token、stream、flow rate、real-time balance、pool(member/distributor)、IDA、sentinels、liquidation、TOGA、@sfpro/sdk、semantic money、yellowpaper、whitepaper

by LeoYeAI
汎用その他⭐ リポ 100

civ-finish-quotes

実質的なタスクが真に完了した際に、文明風の儀式的な引用句を追加します。ユーザーやエージェントが機能追加、リファクタリング、分析、設計ドキュメント、プロセス改善、レポート、執筆タスクといった実際の成果物を完成させるときに、明示的な依頼がなくても使用します。短い返信や小さな修正、未完成の作業には適用しません。

by huxiuhan
汎用その他⭐ リポ 1,110

nookplot

Base(Ethereum L2)上のAIエージェント向け分散型調整ネットワークです。エージェントがオンチェーンアイデンティティを登録する、コンテンツを公開する、他のエージェントにメッセージを送る、マーケットプレイスで専門家を雇う、バウンティを投稿・請求する、レピュテーションを構築する、共有プロジェクトで協業する、リサーチチャレンジを解くことでNOOKをマイニングする、キュレーションされたナレッジを備えたスタンドアロンオンチェーンエージェントをデプロイする、またはアグリーメントとリワードで収益を得る場合に利用できます。エージェントネットワーク、エージェント調整、分散型エージェント、NOOKトークン、マイニングチャレンジ、ナレッジバンドル、エージェントレピュテーション、エージェントマーケットプレイス、ERC-2771メタトランザクション、Prepare-Sign-Relay、AgentFactory、またはNookplotが言及された場合にトリガーされます。

by BankrBot
汎用その他⭐ リポ 59

web3-polymarket

Polygon上でのPolymarket予測市場取引統合です。認証機能(L1 EIP-712、L2 HMAC-SHA256、ビルダーヘッダー)、注文発注(GTC/GTD/FOK/FAK、バッチ、ポストオンリー、ハートビート)、市場データ(Gamma API、Data API、オーダーブック、サブグラフ)、WebSocketストリーミング(市場・ユーザー・スポーツチャネル)、CTF操作(分割、統合、償却、ネガティブリスク)、ブリッジ機能(入金、出金、マルチチェーン)、およびガスレスリレイトランザクションに対応しています。AIエージェント、自動マーケットメーカー、予測市場UI、またはPolygraph上のPolymarketと統合するアプリケーション構築時に活用できます。

by elophanto
汎用その他⭐ リポ 52

ethskills

Ethereum、EVM、またはブロックチェーン関連のリクエストに対応します。スマートコントラクト、dApps、ウォレット、DeFiプロトコルの構築、監査、デプロイ、インタラクションに適用されます。Solidityの開発、コントラクトアドレス、トークン規格(ERC-20、ERC-721、ERC-4626など)、Layer 2ネットワーク(Base、Arbitrum、Optimism、zkSync、Polygon)、Uniswap、Aave、Curveなどのプロトコルとの統合をカバーします。ガスコスト、コントラクトのデシマル設定、オラクルセキュリティ、リエントランシー、MEV、ブリッジング、ウォレット管理、オンチェーンデータの取得、本番環境へのデプロイ、プロトコル進化(EIPライフサイクル、フォーク追跡、今後の変更予定)といったトピックを含みます。

by jiayaoqijia
汎用その他⭐ リポ 44

xxyy-trade

このスキルは、ユーザーが「トークン購入」「トークン売却」「トークンスワップ」「暗号資産取引」「取引ステータス確認」「トランザクション照会」「トークンスキャン」「フィード」「チェーン監視」「トークン照会」「トークン詳細」「トークン安全性確認」「ウォレット一覧表示」「マイウォレット」「AIスキャン」「自動スキャン」「ツイートスキャン」「オンボーディング」「IP確認」「IPホワイトリスト」「トークン発行」「自動売却」「損切り」「利益確定」「トレーリングストップ」「保有者」「トップホルダー」「KOLホルダー」などをリクエストした場合、またはSolana/ETH/BSC/BaseチェーンでXXYYを経由した取引について言及した場合に使用します。XXYY Open APIを通じてオンチェーン取引とデータ照会を実現します。

by Jimmy-Holiday
本サイトは GitHub 上で公開されているオープンソースの SKILL.md ファイルをクロール・インデックス化したものです。 各スキルの著作権は原作者に帰属します。掲載に問題がある場合は info@alsel.co.jp または /takedown フォームよりご連絡ください。
原作者: giuseppe-trisciuoglio · giuseppe-trisciuoglio/developer-kit · ライセンス: MIT