10

I've been using flutter_dotenv to load environment variables saved in .env throughout the application and it's worked just fine to date. As I'm trying to write tests though, I cannot seem to access these from a test file.

import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  setUp(() async {
    await DotEnv().load();
  });

  test('Incorrect password should be rejected', () {
    var password = DotEnv().env['PASSWORD'];
    // stuff
  });
}

Result of running the test:

Shell: [flutter_dotenv] Load failed: file not found
Shell: [flutter_dotenv] No env values found. Make sure you have called DotEnv.load()

It just can't seem to find the .env file. I even made a copy of .env in the test directory but it didn't recognise that either.

I've tried using Platform.environment instead of flutter_dotenv to access the variable, but that didn't work either, returning null.

Apologies if I'm being silly here, it's my first time writing Flutter tests, but would appreciate advice.

Update:

This is what my pubspec.yaml looks like:

name: //name
description: //description

version: 1.0.0+3

environment:
  sdk: ">=2.1.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter
  cupertino_icons: ^0.1.2
  font_awesome_flutter: ^8.5.0
  flutter_youtube: ^2.0.0
  http: ^0.12.0+4
  flutter_dotenv: ^2.1.0
  google_fonts: ^0.3.7
  photo_view: ^0.9.2
  flutter_page_transition: ^0.1.0

dev_dependencies:
  flutter_test:
    sdk: flutter

flutter:
  uses-material-design: true
  assets:
    - images/
    - .env
Ross C
  • 143
  • 1
  • 6
  • Can you post your `pubspec.yaml`? The [flutter_dotenv](https://pub.dev/packages/flutter_dotenv) pub page says that the `.env` file needs to be added as an asset. – Michael Pfaff Mar 14 '20 at 21:13
  • Sorry for the slow response @MichaelP., didn't notice your comment. Have updated my question! – Ross C Mar 15 '20 at 15:31

2 Answers2

17

Add TestWidgetsFlutterBinding.ensureInitialized(); as the first line of your test's main function.

flutter_dotenv is trying to access ServicesBinding mixin which interacts with your app's platform. You need to initialize this binding first before accessing it and the above line of code will ensure this initialization occurs before running your tests.

Your code should look like this:

import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:flutter_test/flutter_test.dart';

void main() async {
  TestWidgetsFlutterBinding.ensureInitialized();
  await DotEnv().load();

  setUp(() {
  // anything else you need to setup
  });

  test('Incorrect password should be rejected', () {
    var password = DotEnv().env['PASSWORD'];
    // stuff
  });
}
Bobsar0
  • 261
  • 3
  • 6
  • 1
    If the test requires an http connection, in the above solution each request will end with an http 400 error. You can bypass the httpClient mock in the following way: import 'dart:io' as io; // new line //... TestWidgetsFlutterBinding.ensureInitialized(); io.HttpOverrides.global = null; // new line – writ3it Aug 28 '21 at 17:58
1

For those having an error of type FileNotFoundError, update flutter_dotenv. From version 5.0.1 there is new method called testLoad() that works as expected because it doesn't use rootBundle to load the file as an asset.