英文:
Flutter test using Mockito - when API for register stub doesn't work
问题
我发表这个问题是因为这种行为对我来说非常奇怪!我不是Mockito的专家,所以这可能只是我的错误。
@GenerateMocks([AuthProvider])
void main() {
test('If there is not a valid session, the data are clean', () async {
UserDataProvider provider = UserDataProvider();
MockAuthProvider mock = MockAuthProvider();
when(mock.isLoggedIn).thenReturn(false);
await provider.update(MockAuthProvider());
expect((await provider.joinedCommunities).isEmpty, true);
});
}
抛出了一个异常
package:mockito/src/mock.dart 191:7 Mock._noSuchMethod
package:mockito/src/mock.dart 185:45 Mock.noSuchMethod
test/provider/user_data_provider_test.mocks.dart 59:33 MockAuthProvider.isLoggedIn
package:unimeet/providers/user_data_provider.dart 22:22 UserDataProvider.update
test/provider/user_data_provider_test.dart 17:20 main.<fn>
MissingStubError: 'isLoggedIn'
No stub was found which matches the arguments of this method call:
isLoggedIn
Add a stub for this method using Mockito's 'when' API, or generate the MockAuthProvider mock with the @GenerateNiceMocks annotation (see https://pub.dev/documentation/mockito/latest/annotations/MockSpec-class.html).
正如您所看到的,我试图为一个简单的getter注册返回值,但却抛出了异常。
请告诉我,谢谢。
英文:
I'm posting this question because this behavior seems very strange to me!
I ain't an expert on mockito, so this may be only my error.
@GenerateMocks([AuthProvider])
void main() {
test('If there is not a valid session, the data are clean', () async {
UserDataProvider provider = UserDataProvider();
MockAuthProvider mock = MockAuthProvider();
when(mock.isLoggedIn).thenReturn(false);
await provider.update(MockAuthProvider());
expect((await provider.joinedCommunities).isEmpty, true);
});
}
An exception is thrown
package:mockito/src/mock.dart 191:7 Mock._noSuchMethod
package:mockito/src/mock.dart 185:45 Mock.noSuchMethod
test/provider/user_data_provider_test.mocks.dart 59:33 MockAuthProvider.isLoggedIn
package:unimeet/providers/user_data_provider.dart 22:22 UserDataProvider.update
test/provider/user_data_provider_test.dart 17:20 main.<fn>
MissingStubError: 'isLoggedIn'
No stub was found which matches the arguments of this method call:
isLoggedIn
Add a stub for this method using Mockito's 'when' API, or generate the MockAuthProvider mock with the @GenerateNiceMocks annotation (see https://pub.dev/documentation/mockito/latest/annotations/MockSpec-class.html).
As you can see I'm trying to register a return value for a simple getter but an exception is thrown.
Let me know and thank you
答案1
得分: 1
你正在添加一个用于 isLoggedIn
字段/获取器的存根:
when(mock.isLoggedIn).thenReturn(false);
但在接下来的一行中,你使用你的模拟对象的全新实例来调用 provider.update
,而不是你存根的那个实例。一个空实例。
解决方案非常简单。只需将构造新实例的部分替换为已经存根的实例,就像这样:
@GenerateMocks([AuthProvider])
void main() {
test('If there is not a valid session, the data are clean', () async {
final provider = UserDataProvider();
final mock = MockAuthProvider();
when(mock.isLoggedIn).thenReturn(false);
await provider.update(mock);
expect((await provider.joinedCommunities).isEmpty, true);
});
}
我还将变量的定义从左侧使用类型更改为 final
关键字,因为在这里使用类型是多余的 - 你已经在右侧的代码中显示了类型给开发人员。在左侧只使用类型,将其标记为 var
,一个可变的变量。默认情况下,将变量定义为 final
,除非确实需要对其进行更改。作为一个经验法则。你仍然可以在 final
中改变对象(比如对 List
使用 add()
),只是不能重新定义变量本身。
如果你永远不打算更改一个变量,请使用 final
或 const
,可以替代 var
或附加到类型。一个 final
变量只能设置一次;一个 const
变量是编译时常数。 (const
变量在隐式情况下也是 final
。)
英文:
What is happening, is you are indeed adding a stub for the mentioned isLoggedIn
field/getter:
when(mock.isLoggedIn).thenReturn(false);
but in the next line, you are calling provider.update
with a brand new instance of your mock. Not the one that you stubbed. An empty one.
The solution is really easy. Simply replace constructing a new instance with your already stubbed instance, like this:
@GenerateMocks([AuthProvider])
void main() {
test('If there is not a valid session, the data are clean', () async {
final provider = UserDataProvider();
final mock = MockAuthProvider();
when(mock.isLoggedIn).thenReturn(false);
await provider.update(mock);
expect((await provider.joinedCommunities).isEmpty, true);
});
}
I also changed the definitions of the variables from using type on the left-hand side to a final
keyword, because type is redundant here - you are already showing the type to the developer that reads the code on the right-hand side. By using only a type on the left side, you mark it as a var
, a mutable variable. Use final
as a default for your variables, except for cases where you indeed want to mutate it. As a rule of thumb. You still can mutate the object (like add()
to a List
) in a final
. Just not redefine the variable itself.
> If you never intend to change a variable, use final or const, either instead of var or in addition to a type. A final variable can be set only once; a const variable is a compile-time constant. (Const variables are implicitly final.)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论