Vin*_*rga 11 provider unit-testing dart flutter
我provider在我们的应用程序中使用该包,我想ChangeNotifier单独测试我的类,以进行简单的单元测试来检查业务逻辑。
除了属性值之外ChangeNotifier,我还想确保在某些情况下(必要时),已notifyListeners调用 ,否则,依赖于此类的最新信息的小部件将不会被更新。
目前,我正在间接测试 是否已notifyListeners被调用:我正在使用这样一个事实:ChangeNotifier允许我使用其方法添加回调addListener。在我添加到测试套件中的回调中,我只需增加一个整数计数器变量并对其进行断言。
这是测试我是否ChangeNotifier调用其侦听器的正确方法吗?有没有更具描述性的方法来测试这个?
这是我正在测试的课程:
import 'package:flutter/foundation.dart';
class ExampleModel extends ChangeNotifier {
int _value = 0;
int get value => _value;
void increment() {
_value++;
notifyListeners();
}
}
Run Code Online (Sandbox Code Playgroud)
这就是我测试它的方法:
import 'package:mobile_app/example_model.dart';
import 'package:test/test.dart';
void main() {
group('$ExampleModel', () {
ExampleModel exampleModel;
int listenerCallCount;
setUp(() {
listenerCallCount = 0;
exampleModel = ExampleModel()
..addListener(() {
listenerCallCount += 1;
});
});
test('increments value and calls listeners', () {
exampleModel.increment();
expect(exampleModel.value, 1);
exampleModel.increment();
expect(listenerCallCount, 2);
});
test('unit tests are independent from each other', () {
exampleModel.increment();
expect(exampleModel.value, 1);
exampleModel.increment();
expect(listenerCallCount, 2);
});
});
}
Run Code Online (Sandbox Code Playgroud)
Bao*_*Ngo 11
你的方法对我来说似乎很好,但如果你想要一种更具描述性的方式,你也可以使用Mockito注册一个模拟回调函数并测试通知程序是否触发以及触发的频率,从而通知你注册的模拟而不是增加计数器:
import 'package:mobile_app/example_model.dart';
import 'package:test/test.dart';
/// Mocks a callback function on which you can use verify
class MockCallbackFunction extends Mock {
call();
}
void main() {
group('$ExampleModel', () {
late ExampleModel exampleModel;
final notifyListenerCallback = MockCallbackFunction(); // Your callback function mock
setUp(() {
exampleModel = ExampleModel()
..addListener(notifyListenerCallback);
reset(notifyListenerCallback); // resets your mock before each test
});
test('increments value and calls listeners', () {
exampleModel.increment();
expect(exampleModel.value, 1);
exampleModel.increment();
verify(notifyListenerCallback()).called(2); // verify listener were notified twice
});
test('unit tests are independent from each other', () {
exampleModel.increment();
expect(exampleModel.value, 1);
exampleModel.increment();
expect(notifyListenerCallback()).called(2); // verify listener were notified twice. This only works, if you have reset your mocks
});
});
}
Run Code Online (Sandbox Code Playgroud)
请记住,如果您在多个测试中触发相同的模拟回调函数,则必须在设置中重置模拟回调函数以重置其计数器。
我遇到了同样的问题。很难测试是否notifyListeners被调用,特别是对于async函数。因此,我将您的想法与listenerCallCount并将其放入您可以使用的一个功能中。
首先你需要一个ChangeNotifier:
class Foo extends ChangeNotifier{
int _i = 0;
int get i => _i;
Future<bool> increment2() async{
_i++;
notifyListeners();
_i++;
notifyListeners();
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
然后函数:
Future<R> expectNotifyListenerCalls<T extends ChangeNotifier, R>(
T notifier,
Future<R> Function() testFunction,
Function(T) testValue,
List<dynamic> matcherList) async {
int i = 0;
notifier.addListener(() {
expect(testValue(notifier), matcherList[i]);
i++;
});
final R result = await testFunction();
expect(i, matcherList.length);
return result;
}
Run Code Online (Sandbox Code Playgroud)
论据:
你ChangeNotifier想要测试的。
应该触发的函数notifyListeners(只是函数的引用)。
您想要在每个 后测试的状态的函数notifyListeners。
每个之后要测试的状态的预期值列表notifyListeners(顺序很重要,长度必须等于调用notifyListeners)。
这是测试的方法ChangeNotifier:
test('should call notifyListeners', () async {
Foo foo = Foo();
expect(foo.i, 0);
bool result = await expectNotifyListenerCalls(
foo,
foo.increment2,
(Foo foo) => foo.i,
<dynamic>[isA<int>(), 2]);
expect(result, true);
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7486 次 |
| 最近记录: |