Dart / Flutter Web单元测试错误:错误:找不到:'dart:html'

时间:2019-09-17 21:50:03

标签: flutter dart flutter-test flutter-web

我正在使用Flutter Web应用程序,但无法进行测试。

Flutter 1.7.8+hotfix.4 • channel stable • git@github.com:flutter/flutter.git
Framework • revision 20e59316b8 (9 weeks ago) • 2019-07-18 20:04:33 -0700
Engine • revision fee001c93f
Tools • Dart 2.4.0

这是pubspec.yaml:

name: web_flutter
description: An app built using Flutter for web

environment:
  # You must be using Flutter >=1.5.0 or Dart >=2.3.0
  sdk: '>=2.3.0-dev.0.1 <3.0.0'

dependencies:
  flutter_web: any
  flutter_web_ui: any
  provider: any
  rxdart: ^0.22.0
  http: ^0.12.0+2
  json_annotation: ^2.4.0
  intl: 0.15.8


dev_dependencies:
  build_runner: ^1.4.0
  build_web_compilers: ^2.0.0
  pedantic: ^1.0.0
  json_serializable: ^3.0.0
  test: any

flutter:
  uses-material-design: true

dependency_overrides:
  flutter_web:
    git:
      url: https://github.com/flutter/flutter_web
      path: packages/flutter_web
  flutter_web_ui:
    git:
      url: https://github.com/flutter/flutter_web
      path: packages/flutter_web_ui
  provider:
    git:
      url: https://github.com/kevmoo/provider
      ref: flutter_web

当我在IDE的终端(VS代码)或终端应用中运行pub run test时,我编写了一些通过的测试。

我遇到的测试需要从项目中导入一些软件包。有了此测试,我会收到错误消息,而其他两个测试则无法运行。我还没有找到解决问题的方法。

这是错误消息:

pub run test                                                                                         MyMac@MyMac
00:06 +0 -1: loading test/service_test.dart [E]                                                                                                                          
  Failed to load "test/service_test.dart":
  Unable to spawn isolate: file:///Users/MyMac/.pub-cache/git/flutter_web-c04fb502b842859de07e36954a9390465a5426c0/packages/flutter_web_ui/lib/ui.dart:12:8: Error: Not found: 'dart:html'
  import 'dart:html' as html;
         ^
  file:///Users/MyMac/.pub-cache/git/flutter_web-c04fb502b842859de07e36954a9390465a5426c0/packages/flutter_web_ui/lib/src/engine.dart:11:8: Error: Not found: 'dart:html'
  import 'dart:html' as html;
         ^
  file:///Users/MyMac/.pub-cache/git/flutter_web-c04fb502b842859de07e36954a9390465a5426c0/packages/flutter_web/lib/src/services/asset_bundle.dart:7:8: Error: Not found: 'dart:html'
  import 'dart:html' show HttpRequest;
         ^
  file:///Users/MyMac/.pub-cache/git/flutter_web-c04fb502b842859de07e36954a9390465a5426c0/packages/flutter_web_ui/lib/src/engine.dart:12:8: Error: Not found: 'dart:js'
  import 'dart:js' as js;
         ^
  file:///Users/MyMac/.pub-cache/git/flutter_web-c04fb502b842859de07e36954a9390465a5426c0/packages/flutter_web_ui/lib/src/engine.dart:13:8: Error: Not found: 'dart:js_util'
  import 'dart:js_util' as js_util;
         ^
  file:///Users/MyMac/.pub-cache/git/flutter_web-c04fb502b842859de07e36954a9390465a5426c0/packages/flutter_web_ui/lib/src/ui/compositing.dart:20:9: Error: Type 'html.Element' not found.
    final html.Element webOnlyRootElement;
          ^^^^^^^^^^^^
  file:///Users/MyMac/.pub-cache/git/flutter_web-c04fb502b842859de07e36954a9390465a5426c0/packages/flutter_web_ui/lib/src/engine.dart:177:37: Error: Type 'html.NodeTreeSanitizer' not found.
  class _NullTreeSanitizer implements html.NodeTreeSanitizer {
                                      ^^^^^^^^^^^^^^^^^^^^^^
  file:///Users/MyMac/.pub-cache/git/flutter_web-c04fb502b842859de07e36954a9390465a5426c0/packages/flutter_web_ui/lib/src/engine.dart:179:21: Error: Type 'html.Node' not found.
    void sanitizeTree(html.Node node) {}
                      ^^^^^^^^^
  file:///Users/MyMac/.pub-cache/git/flutter_web-c04fb502b842859de07e36954a9390465a5426c0/packages/flutter_web_ui/lib/src/engine/bitmap_canvas.dart:26:9: Error: Type 'html.Element' not found.
    final html.Element rootElement = html.Element.tag('flt-canvas');
          ^^^^^^^^^^^^
  file:///Users/MyMac/.pub-cache/git/flutter_web-c04fb502b842859de07e36954a9390465a5426c0/packages/flutter_web_ui/lib/src/engine/bitmap_canvas.dart:28:3: Error: Type 'html.CanvasElement' not found.
    html.CanvasElement _canvas;
    ^^^^^^^^^^^^^^^^^^
00:06 +0 -1: Some tests failed.

如果我注释掉此新测试,则错误仍然存​​在。如果我注释掉测试和相关的导入,则其余两个测试将运行并通过。

这是测试文件(我将有问题的代码注释掉了,以便您轻松查看-希望如此)。

import 'package:test/test.dart';
import 'package:http/http.dart';
import 'package:http/testing.dart';
import 'dart:convert';
import 'package:web_flutter/services/service.dart';
// These are the package imports that cause errors:
import 'package:web_flutter/model/model.dart';
import 'package:web_flutter/data/tenant_view_model.dart';

void main(){

  test("getSubmission returns ResponseData{}", () async {
    // Arrange: setup the test
    final _service = Service();

    _service.httpClient = MockClient((request) async {
      final responseData = {
        "id": "some_id",
        "state": "processed",
        "test": true,
        "editable": false,
        "expires_at": "2019-09-19T03:40:22Z",
        "processed_at": "2019-09-12T03:40:22Z",
        "batch_id": "",
        "download_url": "downloadURl.com",
        "permanent_download_url": "permanentdownloadURL.com"
      };
      return Response(json.encode(responseData),200);
    });

    // Act
    final response = await _service.getSubmission("submissionID");

    // Assert
    expect(response.download_url, "downloadURL.com");
  });
  test("generateForm returns SubmissionResponse{}", () async {
    // Arrange: setup the test
    final _service = Service();

    _service.httpClient = MockClient((request) async {
      final submissionResponse = {
        "status": "success",
        "submission": {
          "id": "some_id",
          "state": "pending",
          "test": false,
          "editable": false,
          "expired": false,
          "expires_at": null,
          "metadata": {
            "foo": 123,
            "bar": "baz"
          },
          "processed_at": null,
          "batch_id": null,
          "data_requests": [],
          "download_url": null,
          "permanent_download_url": null
        }
      };
      return Response(json.encode(submissionResponse),200);
    });

    // Act
    final response = await _service.generateForm(42, "templateID");

    // Assert
    expect(response.submission.id, "some_id");
  });

  test('Tenant View Model generateForm returns tenantVM.submission.submission.id', () async {
    // Arrange
    final _service = Service();
    Tenant tenant;
    tenant.id = 42;

    _service.httpClient = MockClient((request) async {
      final submissionResponse = {
        "status": "success",
        "submission": {
          "id": "some_id",
          "state": "pending",
          "test": false,
          "editable": false,
          "expired": false,
          "expires_at": null,
          "metadata": {
            "foo": 123,
            "bar": "baz"
          },
          "processed_at": null,
          "batch_id": null,
          "data_requests": [],
          "download_url": null,
          "permanent_download_url": null
        }
      };
      return Response(json.encode(submissionResponse),200);
    });
    TenantViewModel tenantVM = TenantViewModel(tenant, _service);

    // Act
    await tenantVM.generateForm("templateID");

    // Assert
    expect(tenantVM.submission.submission.id, "some_id");
  });
}

这是具有我要测试的方法的类(generateForm()

import 'package:flutter_web/cupertino.dart';
import 'package:web_flutter/model/model.dart';
import 'package:web_flutter/services/service.dart';

class TenantViewModel with ChangeNotifier {
  Tenant _tenant;
  Property _property;
  Service _service;
  SubmissionResponse _submission;
  ResponseData _responseData;

  TenantViewModel(this._tenant, this._service);

  bool get isNew => _tenant.id == null;

  set tenant(Tenant tenant) {
    if (_tenant != tenant) {
      _tenant = tenant;
      notifyListeners();
    }
  }

  Tenant get tenant => _tenant;

  set property(Property property) {
    _tenant.propertyId = property.id;
    notifyListeners();
  }

  Property get property => _property;

  set submission(SubmissionResponse submission) {
    if (_submission != submission) {
      _submission = submission;
      notifyListeners();
    }
  }

  SubmissionResponse get submission => _submission;

  set responseData(ResponseData responseData) {
    if (_responseData != responseData) {
      _responseData = responseData;
      notifyListeners();
    }
  }

  ResponseData get responseData => _responseData;

  Future generateForm(String templateID) async {
    SubmissionResponse submission;

    submission = await _service.generateForm(_tenant.id, templateID);
    this.submission = submission;

    notifyListeners();
  }

  Future getSubmission(String submissionID) async {
    ResponseData responseData;

    responseData = await _service.getSubmission(submissionID);
    this.responseData = responseData;

    notifyListeners();
  }

  Future save() async {
    Tenant updatedTenant;
    if (tenant.isNew) {
      updatedTenant = await _service.createTenant(_tenant);
      this.tenant = updatedTenant;
    } else {
      updatedTenant = await _service.updateTenant(tenant);
      this.tenant = updatedTenant;
    }
    notifyListeners();
  }

  Future refresh() async {
    if (isNew) {
      return;
    }
    var updatedTenant = await _service.getTenant(_tenant.id);
    if (_tenant.propertyId != null) {
      _property = await _service.getProperty(_tenant.propertyId);
    }
    _tenant = updatedTenant;
    notifyListeners();
  }
}

我尝试过: import 'package:flutter_test/flutter_test.dart';在测试文件中,并将其添加到pubspec.yaml:

  flutter_test:
    sdk: flutter

这些会导致各种错误,因为我使用的是Flutter Web,而不是Flutter。谁能看到我要去哪里错了?

我知道我正在进行的测试可能是错误的,但是我什至无法理解它运行失败的原因。

8 个答案:

答案 0 :(得分:12)

在开发移动应用程序时遇到了类似的问题,但事实证明,我偶然导入了软件包 dart.html 。我刚刚将其删除,便能够运行该程序。

答案 1 :(得分:1)

当您尝试导入诸如@required 之类的内容时可能会发生这种情况。然后flutter会不小心把import dart.html放在代码上面。只需从代码中删除它,然后您就会解决您的问题。

答案 2 :(得分:0)

之所以出现问题,是因为,正如我的技术负责人指出的那样,“单元测试无法访问dart:html。除非您在浏览器中运行它们。”

来自pub.dev/packages/test:

“默认情况下,测试是在Dart VM [虚拟机]中运行的,但是您也可以通过传递pub run test -p chrome path/to/test.dart在浏览器中运行它们。test将负责启动浏览器,并加载测试,所有结果都会像在VM测试中一样在命令行上报告。实际上,您甚至可以使用一个命令在两个平台上运行测试:pub run test -p "chrome,vm" path/to/test.dart

为解决我的特殊问题,我使用pub run test test/print_reports_card_test.dart -p chrome进行了测试。

答案 3 :(得分:0)

由于您正在运行使用dart:html软件包的Web抖动测试,因此必须以正确的平台为目标。

flutter test --platform chrome

答案 4 :(得分:0)

如果同时对网络和移动设备都进行了测试,则另一种解决方案是在测试文件的顶部添加@TestOn('browser')
这是完整的doc

答案 5 :(得分:0)

import 'dart:html';更改为import 'package:http/http.dart' as http;

然后将pubspec.yaml个文件依赖项更改为

dependencies:
flutter:
sdk: flutter
http:

,然后点击pub get

答案 6 :(得分:0)

我遇到了完全相同的问题。我的问题是我导入了package:url_launcher_web/url_launcher_web.dart,显然您不应该这样做。无论如何,这是一个未使用的导入,所以我将其删除,然后我的手机运行良好。

要修复此问题,请将其删除,问题将得到解决。

为什么会发生此错误: 当不需要导入时分析器会生成此诊断,因为导入库中没有引用任何导入的名称。

示例

以下代码会产生此诊断信息,因为在

中未定义任何内容
dart:async
在库中引用了

import 'dart:async';

void main() {}

常见修补程序

如果不需要导入,则将其删除。

如果打算使用某些导入的名称,则添加缺少的代码。

答案 7 :(得分:0)

enter image description here

当语言模式不合适时,有时会发生此错误。确保“选择语言模式”(图像中的黄色圆圈)处于正确的模式。对于这个例子,我认为应该是 HTML