jinyus / lite_ref

A lightweight dependency injection library for Dart and Flutter.
12 stars 3 forks source link

discussion: Problem with global state when using lite_ref_core during tests. #28

Open yehorh opened 6 months ago

yehorh commented 6 months ago

At the moment, it is not possible to reset the state of all Ref from lite_ref_core objects between tests if they are declared as global variables.

Switching entirely to ScopedRef is challenging because defining asynchronous dependencies requires using overrides during initialization, which is not very convenient.

As an alternative, Refs can be stored in a container and reinitialized between tests.

Are there any other options or ideas for the API on how this can be improved?

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

class Bar {
  Bar(this.value);
  final int value;
}

final foo = Ref.singleton(() => 1);

final bar = Ref.singleton(() {
  return Bar(foo.instance);
});

void main() {
  test('without override', () {
    expect(foo.instance, 1);
    expect(bar.instance.value, 1);
  });

  test('with override', () {
    foo.overrideWith(() => 2);
    expect((foo.instance, bar.instance.value), (2, 2));
  });

  test('without override after override', () {
    expect((foo.instance, bar.instance.value), (1, 1));
  });

  test('override after override', () {
    foo.overrideWith(() => 3);
    expect((foo.instance, bar.instance.value), (3, 3));
  });
}
package:matcher                                     expect
package:flutter_test/src/widget_tester.dart 474:18  expect
test/lite_ref.dart 26:5            main.<fn>

Expected: (int, int):<(2, 2)>
  Actual: (int, int):<(2, 1)>

package:matcher                                     expect
package:flutter_test/src/widget_tester.dart 474:18  expect
test/lite_ref.dart 30:5            main.<fn>

Expected: (int, int):<(1, 1)>
  Actual: (int, int):<(2, 1)>

package:matcher                                     expect
package:flutter_test/src/widget_tester.dart 474:18  expect
test/lite_ref.dart 35:5            main.<fn>

Expected: (int, int):<(3, 3)>
  Actual: (int, int):<(3, 1)>
jinyus commented 6 months ago

I'm not sure using a container would resolve this issue. I think providing async scoped refs might be a better solution.