Dart/Flutter comparer des objets du même type : Expected Instance of `T` Actual Instance of `T`

Bonjour à tous,

Je butte sur un problème de mes tests auto. L’attendu et le résultat sont les mêmes mais il me dit qu’il y a une erreur. Quelqu’un saurait d’où ca peut venir ?

TestFailure (Expected: [
            Instance of 'Month',
            Instance of 'Month',
            Instance of 'Month',
            Instance of 'Month',
            Instance of 'Month',
            Instance of 'Month',
            Instance of 'Month',
            Instance of 'Month',
            Instance of 'Month',
            Instance of 'Month',
            Instance of 'Month',
            Instance of 'Month'
          ]
  Actual: [
            Instance of 'Month',
            Instance of 'Month',
            Instance of 'Month',
            Instance of 'Month',
            Instance of 'Month',
            Instance of 'Month',
            Instance of 'Month',
            Instance of 'Month',
            Instance of 'Month',
            Instance of 'Month',
            Instance of 'Month',
            Instance of 'Month'
          ]
   Which: at location [0] is <Instance of 'Month'> instead of <Instance of 'Month'>

Pendant le débug avant le crash :

image

et le test :

Month(id: 1, month: "J", picking: false)

Merci d’avance !!

Bonjour, tu pourrais mettre le code source de ton test, ainsi que la fonction que tu teste, ça sera plus simple pour voir d’où vient ton problème :).

Bonjour @Lugdu,

Voici mon code source :

import 'package:pickfungi/data_model/fungus.dart';
import 'detail_view.dart';

class DetailViewModel extends IDetailViewModel {
  final Fungus _fungus;
  DetailViewModel(this._fungus);`Texte préformaté`

  @override
  List<Month> get pickingMonth {
    final picking = [
      Month(id: 1, month: "J"),
      Month(id: 2, month: "F"),
      Month(id: 3, month: "M"),
      Month(id: 4, month: "A"),
      Month(id: 5, month: "M"),
      Month(id: 6, month: "J"),
      Month(id: 7, month: "J"),
      Month(id: 8, month: "A"),
      Month(id: 9, month: "S"),
      Month(id: 10, month: "O"),
      Month(id: 11, month: "N"),
      Month(id: 12, month: "D")
    ];
    final pickingPeriod = fungus.pickingPeriod;
    if (pickingPeriod != null) {
      for (var month in pickingPeriod) {
        switch (month) {
          case 1:
            picking[0].picking = true;
            break;
          case 2:
            picking[1].picking = true;
            break;
          case 3:
            picking[2].picking = true;
            break;
          case 4:
            picking[3].picking = true;
            break;
          case 5:
            picking[4].picking = true;
            break;
          case 6:
            picking[5].picking = true;
            break;
          case 7:
            picking[6].picking = true;
            break;
          case 8:
            picking[7].picking = true;
            break;
          case 9:
            picking[8].picking = true;
            break;
          case 10:
            picking[9].picking = true;
            break;
          case 11:
            picking[10].picking = true;
            break;
          case 12:
            picking[11].picking = true;
            break;
          default:
            break;
        }
      }
    }
    return picking;
  }
}

Et voici mon test :

test('pickingPeriod', () {
    final detailViewModel = DetailViewModel(Fungus(
        id: 1,
        scientificName: "",
        commonName: "",
        otherCommonName: ["Cèpe", "Bolet"],
        mainPosterPath: "",
        advice: "",
        edibility: 1,
        posterPath: [],
        pickingPeriod: [5, 6, 7]));
    expect(detailViewModel.pickingMonth, [
      Month(id: 1, month: "J", picking: false),
      Month(id: 2, month: "F", picking: false),
      Month(id: 3, month: "M", picking: false),
      Month(id: 4, month: "A", picking: false),
      Month(id: 5, month: "M", picking: true),
      Month(id: 6, month: "J", picking: true),
      Month(id: 7, month: "J", picking: true),
      Month(id: 8, month: "A", picking: false),
      Month(id: 9, month: "S", picking: false),
      Month(id: 10, month: "O", picking: false),
      Month(id: 11, month: "N", picking: false),
      Month(id: 12, month: "D", picking: false)
    ]);
  });

Le expect va comparer tes objets et se rendre compte que ce sont 2 objets différents…même si ils ont les mêmes contenus de variables.
C’est un peu comme si tu disais que 2 jumeaux étaient la même personne ; ce qui n’est pas le cas.

Quand tu crées tes objets dans ton view model ce ne sont pas les mêmes que quand tu les crées dans ta fonction de test.

Il te faut comparer les valeurs comprises dans chacune de leurs propriétés.

Vérifier que 2 objets sont équivalents

Tu peux ajouter des fonctions l’intérieurs de ta classe Month pour comparer avec un autre objet Month et dire si ils sont équivalents (même si ce sont 2 objets différents).

Ces 2 fonctions sont à redéfinir : l’opérateur == et la propriété calculée hashCode

Exemple (à compléter avec le reste de tes propriétés) :

class Month {
  int id;
  String month;
  
  @override
  bool operator ==(Object o) {
    if (o is Month && o.runtimeType == runtimeType) {
        return o.hashCode == hasCode;
    }
    return false;
  }
  
  @override
  int get hashCode => Object.hash(id, month) ;
}

Si tu comprends l’anglais tu as une vidéo dédiée de l’équipe officielle de Dart/Flutter :

PS : Si tu as des objets imbriqués, alors tu devrais faire pareil dans chacune des classes de tes propriétés

Super !! Merci Maxime. Ce sujet avait été évoqué en coatching il y a quelques temps, mais j’ai pas fait le rapprochement. Je vais pouvoir finir mes tests :grin:

1 « J'aime »