😇

Converting object to an encodable object failed: Instace of 'DateTime'

2024/07/16に公開

Error DateTime???

Supabaseのコードが実行できているか、Unit Testをしたかった。mockがないようなので、自作しなければならないらしいが、今回やりたいことは、テスト用のテーブルに直接データを保存すること。
直接ぶち込みたいわけですよ。

こちらが、INSERTするメソッドを持っているクラス。

import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:workstream_prod/infrastructure/supabase_provider/supabase_provider.dart';
part 'task_api.g.dart';

(keepAlive: true)
TaskApi taskApi(TaskApiRef ref) {
  return TaskApi(ref);
}

final class TaskApi {
  TaskApi(this.ref);
  Ref ref;

  /// 自動連番の場合は、freezedを使わない方が良さそう。
  Future<void> createTask({
    required String status,
    required String task_name,
    required int goal_id,
  }) async {
    try {
      /// UTC Japan GMT+0900 (日本標準時)
      final now = DateTime.now().toUtc().toIso8601String();

      /// auth uuid
      final uuid = ref.read(supabaseClientProvider).auth.currentUser?.id;
      await ref.read(supabaseClientProvider).from('d_task').insert({
        'status': status,
        'task_name': task_name,
        'goal_id': goal_id,
        'created_at': now,
        'updated_at': now,
        'uuid': uuid,
      });
    } on Exception catch (e) {
      throw Exception('Failed to create task: $e');
    }
  }
}

ProviderContainerを作成する。Dartでは、これが、 DIコンテナらしい。URLとanon keyは、.envから読み込めなかったので、ハードコーディングしてます。

import 'package:flutter_test/flutter_test.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
import 'package:workstream_prod/application/test_api/todo_api.dart';

void main() {
  // setUpAllの中で、Supabaseの初期化を行う
  setUpAll(() async {
    // Set initial values for shared preferences
    SharedPreferences.setMockInitialValues({});

    const url = 'https:/******';
    const anonKey = 'ey***********k';
    await Supabase.initialize(url: url, anonKey: anonKey);
  });

  test('insert test', () async {
    final todoApi = TodoAPi();
    await todoApi.insertTodo(title: '買い物にいく');
  });
}

最初コード書いたときにエラーでハマった。RLSの解除をしてなかったのと、DateTimeの設定が良くなかった笑
日本時間に合わせていないのと、エンコードができなかったようだ。

// 日本時間に合わせる
final now = DateTime.now().toUtc().toIso8601String();

修正したらテスト通った🙌
上のソースコードは修正済み。

最後に

fake_supabaseなるパッケージでも作ってくれるとありがたいですね。テスト用のテーブル保存したいという目的があってやりましたが、本当はDBに保存するのってよくないのでしょうね。

Discussion