Skip to content

Can not override clock.now() for Widget integration tests #2142

@RustamG

Description

@RustamG

Hi,

I'm trying to implement golden tests (compare app screenshots) for a project where the UI depends on the current date/time. I believe the most suggested solution to mock DateTime.now() is to use clock package. However, I can't get it to work inside the widgets.

Minimal reproduction code repo (no golden tests, though): link.

Code snippet

main.dart

import 'package:clock/clock.dart';
import 'package:flutter/material.dart';

const kCurrentYearKey = 'current_year_key';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _currentYear = 0;

  @override
  void initState() {

    _currentYear = clock.now().year;
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Mock current year'),
      ),
      body: Center(
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text('Current year is: '),
            Text(
              '$_currentYear',
              key: const ValueKey(kCurrentYearKey),
              style: Theme.of(context).textTheme.headlineMedium,
            ),
          ],
        ),
      ),
    );
  }
}

integration_test/widget_test.dart

import 'package:clock/clock.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:mock_current_date_in_integration_tests/main.dart';

const mockedCurrentYear = 1999;
final mockedClock = Clock.fixed(DateTime(mockedCurrentYear));

void main() async {
  await withClock(mockedClock, () async { // wrap 1

    IntegrationTestWidgetsFlutterBinding.ensureInitialized();

    await withClock(mockedClock, () async { // wrap 2

      testWidgets('Current year is mocked to be 1999', (WidgetTester tester) async {

        await withClock(mockedClock, () async { // wrap 3

          expect(clock.now().year, 1999); // passes. Thanks to 'wrap 3'
          await tester.pumpWidget(const MyApp());
          final finder = find.byKey(const ValueKey(kCurrentYearKey));
          var currentYearText = finder.evaluate().single.widget as Text;
          expect(currentYearText.data, '1999'); // fails
        });
      });
    });
  });
}

Issue which might be related: flutter/flutter#96939

Checked on the latest Flutter (v3.32.8) in iOS simulator with latest clock (v1.1.2).

Please let me know if there is a solution for this or I'd better post it somewhere else.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions