Flutter(Dart)でユニットテストを書く


背景

割と複雑なJSONをAPIから取得する処理を実装していた際、JSONからのシリアライズが正常に出来るか確認したくなりました。

そこで今回は、ユニットテストで確認してみることにしました。

この記事では、ユニットテストの導入とその際にハマったポイントを記載します。


参考


実装


テストパッケージのインストール

pubspec.yamlに依存関係を追加します。

(恐らく、Flutterプロジェクトを生成した際に既に追加されていると思います。)


pubspec.yaml

dev_dependencies:

flutter_test:
sdk: flutter


The test package provides the core framework for writing unit tests, and the flutter_test package provides additional utilities for testing widgets.

An introduction to unit testingより引用。)


引用文に記載の通り、testパッケージはユニットテスト用のパッケージ、flutter_testパッケージはユニットテストに追加してWidgetのテストに関するユーティリティを提供しているので、ひとまずflutter_testを入れておけばユニットテストも実装できます。

その後の実装は公式リファレンスを読んでいただければ解説は不要かと思いますので、ここからは私が実装の際にハマったポイントを記載していきます。


ハマりポイント


オブジェクト同士の比較が失敗する

試しにシンプルなオブジェクトのユニットテストを書いて見たところ、テストが失敗しました。


sample.dart

import 'package:json_annotation/json_annotation.dart';

@JsonSerializable(createToJson: false)
class Sample {
Sample({this.name, this.value});

final String name;
final int value;

static fromJson(Map<String, dynamic> json) => _$SampleFromJson(json);
}



sample_test.dart

import 'package:flutter_test/flutter_test.dart';

const Map<String, dynamic> TEST_DATA = {
"name": "ほげ",
"value": 100,
};

void main() {
test(
"Sampleクラスのテスト",
() {
expect(Sample.fromJson(TEST_DATA), equals(Sample(name: "ほげ", value: 100)));
},
);
}



失敗時のログ

Expected: <Instance of 'Sample'>

Actual: <Instance of 'Sample'>

どうやら原因は、Sampleクラスの==hashCodeを実装していなかったことにあったようです。

下記のようにoverrideした結果、無事テストが成功しました。

dart:uiパッケージのhashValues@mkosukeさんに教えていただきました!ありがとうございます!)


Sample.dart

import 'package:json_annotation/json_annotation.dart';

import 'dart:ui';

@JsonSerializable(createToJson: false)
class Sample {
Sample({this.name, this.value});

final String name;
final int value;

@override
bool operator ==(other) =>
other is Sample && other.name == name && other.value == value;

@override
int get hashCode => hashValues(name, value);

static fromJson(Map<String, dynamic> json) => _$SampleFromJson(json);
}