How to access Flutter environment variables from tests?
Asked Answered
H

3

11

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
Haemoglobin answered 14/3, 2020 at 19:53 Comment(2)
Can you post your pubspec.yaml? The flutter_dotenv pub page says that the .env file needs to be added as an asset.Ariella
Sorry for the slow response @MichaelP., didn't notice your comment. Have updated my question!Haemoglobin
E
18

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
  });
}
Equestrian answered 1/4, 2020 at 2:45 Comment(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 lineCurable
R
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.

Rockie answered 5/2, 2022 at 20:1 Comment(0)
F
0

Below solutions works for me.

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

void main() async {


  setUp(() {
    dotenv.testLoad(
        fileInput: '''
          PASSWORD=TEST_PASSWORD 
          KEY2=VALUE2
          KEY3=VALUE3
      ''',
      );
  });

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

in pubspec.yaml

flutter_dotenv: ^5.1.0
Fayre answered 8/8 at 15:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.