英文:
Flutter Unit test: Bad state: No method stub was called from within `when()`. Was a real method called, or perhaps an extension method?
问题
我正在尝试模拟一个来自第三方库的流,以便在我的单元测试中使用(使用 mocktail):
这是我的测试代码:
void main() {
late AirPodsMotionProvider airPodsMotionProvider;
final mockDeviceMotionData = DeviceMotionDataMocks();
setUp(() {
WidgetsFlutterBinding.ensureInitialized();
airPodsMotionProvider = AirPodsMotionProvider();
});
group('test AirPodsMotionProvider', () {
group('test listenForAirPodsMotionData', () {
test('test listen for incoming data', () async {
final value = mockDeviceMotionData.mockDefaultDeviceMotionData;
when(
() => airPodsMotionProvider.listenForAirPodsMotionData(),
).thenAnswer((_) => Stream<DeviceMotionData>.value(value));
airPodsMotionProvider.listenForAirPodsMotionData().listen(
expectAsync1(
(event) {
expect(event, value);
},
),
);
});
});
});
}
我编写了一个包装第三方库功能的提供程序,称为 AirPodsMotionProvider,它看起来像这样:
class AirPodsMotionProvider {
Stream<DeviceMotionData> listenForAirPodsMotionData() =>
FlutterAirpods.getAirPodsDeviceMotionUpdates;
}
我的问题是如何使流返回具有特定值的流。我阅读了一些答案,其中提到我需要做类似以下的事情:
class MockFlutterAirpods extends Mock implements FlutterAirPods {}
然后使该函数返回一个特定的函数,但对我来说并没有完全奏效。
英文:
I am trying to mock a stream in my unit test (using mocktail) that comes from a third-party library:
This my test code:
void main() {
late AirPodsMotionProvider airPodsMotionProvider;
final mockDeviceMotionData = DeviceMotionDataMocks();
setUp(() {
WidgetsFlutterBinding.ensureInitialized();
airPodsMotionProvider = AirPodsMotionProvider();
});
group('test AirPodsMotionProvider', () {
group('test listenForAirPodsMotionData', () {
test('test listen for incoming data', () async {
final value = mockDeviceMotionData.mockDefaultDeviceMotionData;
when(
() => airPodsMotionProvider.listenForAirPodsMotionData(),
).thenAnswer((_) => Stream<DeviceMotionData>.value(value));
airPodsMotionProvider.listenForAirPodsMotionData().listen(
expectAsync1(
(event) {
expect(event, value);
},
),
);
});
});
});
}
I have written a provider which wraps the third party's library functionality called AirPodsMotionProvider and it looks like this:
class AirPodsMotionProvider {
Stream<DeviceMotionData> listenForAirPodsMotionData() =>
FlutterAirpods.getAirPodsDeviceMotionUpdates;
}
My question is how can I make the stream return the stream with a specific value.
I read some answers mentioning I need to do something like:
class MockFlutterAirpods extends Mock implements FlutterAirPods {}
And then make that function return a specific function, but it didn't work for me exactly.
答案1
得分: 1
你的 airPodsMotionProvider
必须是一个模拟对象,这个 Mock
子类可以让你使用 when
来存根化它的方法。
因此,你需要一个模拟类:
class MockAirPodsMotionProvider extends Mock implements AirPodsMotionProvider {}
然后在你的 setUp
中,你使用这个类来初始化你的 airPodsMotionProvider
- MockAirPodsMotionProvider
。
接下来对 when
的调用将按预期工作。但是在这个测试中,你实际上是在测试这个模拟对象。你可能希望将这个模拟对象传递给依赖于 AirPodsMotionProvider
的类,以测试这个类的行为,而不是模拟对象本身,因为它只是一个模拟对象,没有模拟对象所模拟的逻辑。
英文:
Your airPodsMotionProvider
must be a mock, this Mock
child class so that you will be able to stub its methods with when
.
So you need a mocked class:
class MockAirPodsMotionProvider extends Mock implements AirPodsMotionProvider {}
and then in your setUp
you initialize your airPodsMotionProvider
with such class - MockAirPodsMotionProvider
.
The further call to when
will then work as expected. But what you do in this test is you actually test the mock. You may want to pass this mock to a class that depends on the AirPodsMotionProvider
to test this class's behavior, not the mock itself, as it's just a mock. It doesn't have the logic of what it mocks.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论