0

am manually setting up a model class with json (de)serialization. By now I have implemented some testcases. In particular one where I check if toJson -> fromJson is the identity for my model type called Session.

Here is the relevant part of my model type:

class Session extends Equatable {
  final List<User> audience;

/* ... */

  Session.fromJson(Map<String, dynamic> json) :
        /* ... */
         audience = (json['audience'] as List).map(((it) => 
              User.fromMap(it))).toList();

  Map<String, dynamic> toJson() => {
      /* ... */
      'audience': audience.map((it) => it.toJson()).toList()
    };
}

These are the types in the audience field:

class User extends Equatable {
  factory User.fromJson(Map<String, dynamic> json) {
    if (_isRegisteredUserJson(json)) {
      return RegisteredUser.fromMap(json);
    } else {
      return User(id: json['id']);
    }
  } 

/* ... */
}

class RegisteredUser extends User {/* ... */}

In my test I set up the audience field (using the faker library) like so:


User _user() => User(id: faker.guid.guid());

RegisteredUser _registeredUser() => RegisteredUser(
    id: faker.guid.guid(),
    alias: faker.person.name(),
    email: faker.internet.email());


Session _session => Session(
    audience: faker.randomGenerator
        .amount((n) => n % 3 == 0 ? _registeredUser() : _user, 100)
        .cast<User>()
/* ... */
);

I expect the audience List to contain only elements of type User or RegisteredUser after toJson() returns. Instead I get A List containing either RegisteredUsers or _Closure: () => 'User from Function' which I am not exactly sure about what that is. As a result I get the following Error Message for my test:

00:00 +4 -1: toJson -> fromJson is identity for Session [E]
  type '() => User' is not a subtype of type 'User' in type cast
  dart:_internal/cast.dart 99:46                     _CastListBase.[]
  dart:collection/list.dart 60:33                    __CastListBase&_CastIterableBase&ListMixin.elementAt
  dart:_internal/iterable.dart 414:40                MappedListIterable.elementAt
  dart:_internal/iterable.dart 219:19                ListIterable.toList
  package:feedback/model/base_module.dart 42:54      BaseModule.toJson
  package:feedback/model/session.dart 51:23          Session.toJson
  test/json_test.dart 34:47                          main.<fn>.<fn>
  package:test_api/src/backend/declarer.dart 168:27  Declarer.test.<fn>.<fn>.<fn>
  ===== asynchronous gap ===========================
  dart:async/future_impl.dart 22:43                  _Completer.completeError
  dart:async/runtime/libasync_patch.dart 40:18       _AsyncAwaitCompleter.completeError
  package:test_api/src/backend/declarer.dart         Declarer.test.<fn>.<fn>.<fn>
  ===== asynchronous gap ===========================
  dart:async/zone.dart 1053:19                       _CustomZone.registerUnaryCallback
  dart:async/runtime/libasync_patch.dart 77:23       _asyncThenWrapperHelper
  package:test_api/src/backend/declarer.dart         Declarer.test.<fn>.<fn>.<fn>
  package:test_api/src/backend/invoker.dart 250:15   Invoker.waitForOutstandingCallbacks.<fn>
  ===== asynchronous gap ===========================
  dart:async/zone.dart 1045:19                       _CustomZone.registerCallback
  dart:async/zone.dart 962:22                        _CustomZone.bindCallbackGuarded
  dart:async/timer.dart 52:45                        new Timer
  dart:async/timer.dart 87:9                         Timer.run
  dart:async/future.dart 174:11                      new Future
  package:test_api/src/backend/invoker.dart 399:21   Invoker._onRun.<fn>.<fn>.<fn>

00:00 +4 -1: Some tests failed.

Unhandled exception:
Dummy exception to set exit code.
#0      _rootHandleUncaughtError.<anonymous closure> (dart:async/zone.dart:1112:29)
#1      _microtaskLoop (dart:async/schedule_microtask.dart:41:21)
#2      _startMicrotaskLoop (dart:async/schedule_microtask.dart:50:5)
#3      _Timer._runTimers (dart:isolate/runtime/libtimer_impl.dart:391:30)
#4      _Timer._handleMessage (dart:isolate/runtime/libtimer_impl.dart:416:5)
#5      _RawReceivePortImpl._handleMessage (dart:isolate/runtime/libisolate_patch.dart:171:12)
fxvdh
  • 147
  • 9
  • As error said, you need to return a `User` instead of closure(`() => User`). Go to the relevant line and return a `User` – Blasanka May 07 '19 at 15:23
  • First, get rid of unnecessary bracket in this line: `audience = (json['audience'] as List).map(((it) => User.fromMap(it))).toList();` – Blasanka May 07 '19 at 15:26
  • And the fat arrow(`=>`) here `Map toJson() => { /* ... */ 'audience': audience.map((it) => it.toJson()).toList() };` – Blasanka May 07 '19 at 15:27
  • Sorry, there is no line (that I know of) where I return that type. The fat arrow is necessary, because I return a Map literal. – fxvdh May 07 '19 at 15:27
  • `.amount` returns a `List` and you're trying to cast it to a `User` – Jordan Davies May 07 '19 at 15:28
  • @jordan No, [cast](https://api.dartlang.org/stable/2.3.0/dart-core/Iterable/cast.html) casts the elements in the list. – fxvdh May 07 '19 at 15:31
  • ohh its because when you call `_user` there's no brackets, so you're returning the closure. – Jordan Davies May 07 '19 at 15:31
  • @jordan Thats not the case, I provided the full implementation for that method in an edit now. – fxvdh May 07 '19 at 15:34
  • 1
    `.amount((n) => n % 3 == 0 ? _registeredUser() : _user, 100)` should be `.amount((n) => n % 3 == 0 ? _registeredUser() : _user(), 100)` notice the brackets on the `_user` call – Jordan Davies May 07 '19 at 15:35
  • @jordan, oh well, yeah thank you very much! :D – fxvdh May 07 '19 at 15:36

1 Answers1

0

Thanks to Jordan Davies, here is the answer:

In the method call _user I accidentally omitted the brackets and therefore passed a function as parameter where I wanted the result of that function.

fxvdh
  • 147
  • 9