如何用参数验证模拟方法



我正在测试存储库方法。我为api调用添加了存根

when(appApiService.changeCardStatus(
cardId, ChangeCardStatusRequest(status: CARD_STATUS_ELIGIBLE)))
.thenAnswer((_) async => HttpResponse(
true,
Response(
requestOptions: RequestOptions(path: ''),
statusCode: successStatusCode,
data: true)));

然后我调用repo方法await repositoryImpl.doEligibleCard(cardId: cardId, isEligible: isEligible);我的api方法应该调用。然后验证

verify(appApiService.changeCardStatus(
cardId, ChangeCardStatusRequest(status: CARD_STATUS_ELIGIBLE)));

但是,我的测试失败了

package:test_api                                                                              fail
package:mockito/src/mock.dart 714:7                                                           _VerifyCall._checkWith
package:mockito/src/mock.dart 991:18                                                          _makeVerify.<fn>
test/unit/repository_test/my_cards_repository_impl/my_cards_repository_impl_test.dart 278:11  main.<fn>
No matching calls. All calls: MockAppApiServiceTest.changeCardStatus('55', Instance of 'ChangeCardStatusRequest')
(If you called `verify(...).called(0);`, please instead use `verifyNever(...);`.)

失败,因为我使用ChangeCardStatusRequest作为api方法的参数,这就是为什么验证没有看到api调用。那么如何用ChangeCardStatusRequest这样的类参数来验证方法呢?

my API method

@POST('/cards/{cardId}/status')
Future<HttpResponse> changeCardStatus(
@Path("cardId") String cardId, @Body() ChangeCardStatusRequest changeCardStatusRequest);

my repository method

@override
Future<DataState<bool>> doEligibleCard({required String cardId, required bool isEligible}) async {
return await doSafeApiCall(
() async => await _appApiService.changeCardStatus(
cardId,
ChangeCardStatusRequest(
status: isEligible ? CARD_STATUS_ELIGIBLE : CARD_STATUS_INELIGIBLE)),
(responseData) => isEligible);
}

Make ChangeCardStatusRequest扩展Equtable以便能够比较

也是一个旁注,使用when而不将其附加到特定参数,传递any()代替,所以不用

when(appApiService.changeCardStatus(
cardId, ChangeCardStatusRequest(status: CARD_STATUS_ELIGIBLE)))
.thenAnswer((_) async => HttpResponse(
true,
Response(
requestOptions: RequestOptions(path: ''),
statusCode: successStatusCode,
data: true))); 

when(appApiService.changeCardStatus(
any(), any()))
.thenAnswer((_) async => HttpResponse(
true,
Response(
requestOptions: RequestOptions(path: ''),
statusCode: successStatusCode,
data: true))); 

,但它只能通过添加In test setUpAll这行自定义类

来工作
registerFallbackValue(ChangeCardStatusRequest());

我认为你需要一个像argThat这样的参数匹配器,并且你还需要给出预期的调用次数。

可能像这样:

verify(appApiService.changeCardStatus(
cardId, 
argThat((request) => request.status == CARD_STATUS_ELIGIBLE))).called(1);

如果您正在验证的方法具有非空参数,则需要在Mock类中重写它,如下所述:

用非空参数类型手动重写方法。

在您的示例中,这可能看起来像:

class MockApiService extends Mock implements ApiService {
@override
void changeCardStatus(int? cardID, ChangeCardStatusRequest? request) =>
super.noSuchMethod(Invocation.method(#changeCardStatus, [cardID, request]));
}

最新更新