1

我在单元测试中使用 Equatable 来比较 2 个对象。这是我从 Equatable 扩展的对象:

import 'dart:convert';

import 'package:equatable/equatable.dart';

class VenuesDetails extends Equatable {
  Response response;

  VenuesDetails({
    this.response,
  });

  factory VenuesDetails.fromJson(Map<String, dynamic> json) => VenuesDetails(
        response: Response.fromJson(json["response"]),
      );

  Map<String, dynamic> toJson() => {
        "response": response.toJson(),
      };

  @override
  List<Object> get props => [response];
}

class Response extends Equatable {
  Venue venue;

  Response({
    this.venue,
  });

  factory Response.fromJson(Map<String, dynamic> json) => Response(
        venue: Venue.fromJson(json["venue"]),
      );

  Map<String, dynamic> toJson() => {
        "venue": venue.toJson(),
      };

  @override
  List<Object> get props => [venue];
}

class Venue extends Equatable {
  String id;
  String name;
  Contact contact;
  Location location;
  String canonicalUrl;
  List<Category> categories;
  int createdAt;
  String shortUrl;
  String timeZone;

  Venue({
    this.id,
    this.name,
    this.contact,
    this.location,
    this.canonicalUrl,
    this.categories,
    this.createdAt,
    this.shortUrl,
    this.timeZone,
  });

  factory Venue.fromJson(Map<String, dynamic> json) => Venue(
        id: json["id"],
        name: json["name"],
        contact: Contact.fromJson(json["contact"]),
        location: Location.fromJson(json["location"]),
        canonicalUrl: json["canonicalUrl"],
        categories: List<Category>.from(
            json["categories"].map((x) => Category.fromJson(x))),
        createdAt: json["createdAt"],
        shortUrl: json["shortUrl"],
        timeZone: json["timeZone"],
      );

  Map<String, dynamic> toJson() => {
        "id": id,
        "name": name,
        "contact": contact.toJson(),
        "location": location.toJson(),
        "canonicalUrl": canonicalUrl,
        "categories": List<dynamic>.from(categories.map((x) => x.toJson())),
        "createdAt": createdAt,
        "shortUrl": shortUrl,
        "timeZone": timeZone,
      };

  @override
  List<Object> get props => [
        id,
        name,
        contact,
        location,
        canonicalUrl,
        categories,
        createdAt,
        shortUrl,
        timeZone,
      ];
}

class Category extends Equatable {
  String id;
  String name;
  String pluralName;
  String shortName;
  Icon icon;
  bool primary;

  Category({
    this.id,
    this.name,
    this.pluralName,
    this.shortName,
    this.icon,
    this.primary,
  });

  factory Category.fromJson(Map<String, dynamic> json) => Category(
        id: json["id"],
        name: json["name"],
        pluralName: json["pluralName"],
        shortName: json["shortName"],
        icon: Icon.fromJson(json["icon"]),
        primary: json["primary"],
      );

  Map<String, dynamic> toJson() => {
        "id": id,
        "name": name,
        "pluralName": pluralName,
        "shortName": shortName,
        "icon": icon.toJson(),
        "primary": primary,
      };

  @override
  List<Object> get props => [
        id,
        name,
        pluralName,
        shortName,
        icon,
        primary,
      ];
}

class Icon extends Equatable {
  String prefix;
  String suffix;

  Icon({
    this.prefix,
    this.suffix,
  });

  factory Icon.fromJson(Map<String, dynamic> json) => Icon(
        prefix: json["prefix"],
        suffix: json["suffix"],
      );

  Map<String, dynamic> toJson() => {
        "prefix": prefix,
        "suffix": suffix,
      };

  @override
  List<Object> get props => [
        prefix,
        suffix,
      ];
}

class Contact extends Equatable {
  Contact();

  factory Contact.fromJson(Map<String, dynamic> json) => Contact();

  Map<String, dynamic> toJson() => {};

  @override
  List<Object> get props => [];
}

class Location extends Equatable {
  double lat;
  double lng;
  List<LabeledLatLng> labeledLatLngs;
  String cc;
  String country;
  List<String> formattedAddress;

  Location({
    this.lat,
    this.lng,
    this.labeledLatLngs,
    this.cc,
    this.country,
    this.formattedAddress,
  });

  factory Location.fromJson(Map<String, dynamic> json) => Location(
        lat: json["lat"].toDouble(),
        lng: json["lng"].toDouble(),
        labeledLatLngs: List<LabeledLatLng>.from(
            json["labeledLatLngs"].map((x) => LabeledLatLng.fromJson(x))),
        cc: json["cc"],
        country: json["country"],
        formattedAddress:
            List<String>.from(json["formattedAddress"].map((x) => x)),
      );

  Map<String, dynamic> toJson() => {
        "lat": lat,
        "lng": lng,
        "labeledLatLngs":
            List<dynamic>.from(labeledLatLngs.map((x) => x.toJson())),
        "cc": cc,
        "country": country,
        "formattedAddress": List<dynamic>.from(formattedAddress.map((x) => x)),
      };

  @override
  List<Object> get props => [
        lat,
        lng,
        labeledLatLngs,
        cc,
        country,
        formattedAddress,
      ];
}

class LabeledLatLng extends Equatable {
  String label;
  double lat;
  double lng;

  LabeledLatLng({
    this.label,
    this.lat,
    this.lng,
  });

  factory LabeledLatLng.fromJson(Map<String, dynamic> json) => LabeledLatLng(
        label: json["label"],
        lat: json["lat"].toDouble(),
        lng: json["lng"].toDouble(),
      );

  Map<String, dynamic> toJson() => {
        "label": label,
        "lat": lat,
        "lng": lng,
      };

  @override
  List<Object> get props => [
        label,
        lat,
        lng,
      ];
}

我编写此测试以从远程存储库获取数据:

test('应该在响应码为200(成功)时执行get请求', () async {

when(mockHttpCLient.get(any, headers: anyNamed('headers'))).thenAnswer(
    (_) async => http.Response(fixture('venues_details.json'), 200));

final result = await foursquareRepositoryImpl.getVenuesDetails(venueId);

expect(result, venue);
  },
);

但在expect(result, venue);我得到这个错误:

 getVenuesDetails should perform a get request when the response code is 200 (success):

ERROR: Expected: VenuesDetails:<VenuesDetails>
  Actual: VenuesDetails:<VenuesDetails>

package:test_api                                            expect
package:flutter_test/src/widget_tester.dart 234:3           expect
test/repository/foursquare_repository_impl_test.dart 110:9  main.<fn>.<fn>

我的错误在哪里使用Equatable

4

1 回答 1

3

正如 pub.dev 上的包页面所引用的:

注意:Equatable 被设计为仅适用于不可变对象,因此所有成员变量都必须是最终的(这不仅仅是 Equatable 的一个特性 - 用可变值覆盖 hashCode 可能会破坏基于哈希的集合)。

我注意到你的字段不是最终的,所以这可能打破了平等

于 2020-04-21T19:09:23.837 回答