1

I'm new to dart and trying out testing. My first programm is a command line tool that takes user input. How can I simulate that during testing?

My function lets the user choose an item out of a list. I'd like to write tests if the function successfully rejects integers too small or too big entered via "readLineSync".

How to create the input in a test? (using test.dart)

JasonTS
  • 2,479
  • 4
  • 32
  • 48

1 Answers1

0

If you are using stdin to collect input you can use IOOverrides to override the behavior of stdin. The example I'm using requires you to install mocktail as a dev dependency. Given the funtion:

String? collect() => stdin.readLineSync();

I want to provide my own input during testing:

import 'dart:io' hide stdin;

import 'package:example/example.dart' show collect;
import 'package:mocktail/mocktail.dart';
import 'package:test/test.dart';

class FakeStdin extends Mock implements Stdin {}

void main() {
  test('collect returns input', () {
    final stdin = FakeStdin();

    when(() => stdin.readLineSync()).thenReturn('input!');

    IOOverrides.runZoned(
      () {
        expect(collect(), equals('input!')); // passes!
      },
      stdin: () => stdin,
    );
  });
}
Apealed
  • 1,415
  • 8
  • 29
  • Having an extra dependency just for one test seems a bit much. Is that possible only using dart core functionality? – JasonTS Apr 19 '23 at 08:58
  • 1
    @JasonTS it is possible. But it will require a more leg work for this test and future tests with `Stdin` to create the fake responses you need. First, remove the `mocktail` dependecy. Next, only write your class as `class FakeStdin implements Stdin { ... }`. Third, override `noSuchMethod` in the `FakeStdin` class. Override the `readLineSync` method to return the response you like to test with. Now you should be able to use an instance of this `FakeStdin`in the `IOOverrides` – Apealed Apr 19 '23 at 14:00