'Mock JS object in tests on browser platform

I have this simplified dart file using dart:js:

(dataLayer is used for Google tags, if that's any help)

@JS()
import 'package:js/js.dart';

@JS('dataLayer.push')
external void _push(data);

class Manager {
  void pushEvent(String event) {
    _push(event);
  }
}

On the web, it runs correctly and the dataLayer object is being created in a script in the web/index.html file.


I am trying to write a test about it. I would like to verify dataLayer.push is being called with the correct parameters.

I run my test with the command

flutter test --platform chrome

But I get this error:

TypeError: Cannot read properties of undefined (reading 'push')

Is it possible to create a dummy dataLayer variable (and maybe have the hand on it to record the calls to the method .push())? If yes, how?

Here is my attempt:

@TestOn('browser')

import 'package:flutter_test/flutter_test.dart';
import 'package:js/js.dart';
import 'my_project/my_file.dart';

class _DataLayer {
  void push(dynamic data) {}
}

@JS('dataLayer')
final dataLayer = _DataLayer();

void main() {
  test('It should push the event', () {
    Manager().pushEvent('myEvent');
  });
}


Solution 1:[1]

A way to do it would be to load and use a custom HTML file during the tests where you can include a script to create the js variables you need.

Follow the instructions of the package test.

If your test file name is folder/my_test.dart, then you can create a html file named (folder/my_test.html):

<!doctype html>
<html>

<head>
  <title>Custom HTML file title</title>
  <link rel="x-dart-test" href="my_test.dart">
  <script src="packages/test/dart.js"></script>
  <script>
    window['dataLayer'] = [];
  </script>
</head>

</html>

See this StackOverflow answer and this StackOverflow question.

and then you can run

dart test --platform chrome

However, this is only supported with dart test and not flutter test, see this issue. In it, they recommend writing an integration test instead.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Valentin Vignal