skip to Main Content

I am testing repository method.
I add stub for api call

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

then i call repo method await repositoryImpl.doEligibleCard(cardId: cardId, isEligible: isEligible); my api method should called. then i verify

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

But, my test feiled

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(...);`.)

Failed, because i use ChangeCardStatusRequest as a parameter to api method and that is why verify not see api call.So how to verify method with class parameter like 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);
  }

2

Answers


  1. I think you need an argument matcher like argThat here, and also you need to give the expected number of calls with called.

    Possibly like this:

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

    If the method you are verifying has non-nullable arguments, you need to override it in you Mock class, as described here:

    Manually override a method with a non-nullable parameter type.

    In your case this might look like:

    class MockApiService extends Mock implements ApiService {
      @override
      void changeCardStatus(int? cardID, ChangeCardStatusRequest? request) =>
        super.noSuchMethod(Invocation.method(#changeCardStatus, [cardID, request]));
    }
    
    Login or Signup to reply.
  2. Make ChangeCardStatusRequest extends Equtable to be able to compare

    Also a side note, to use when without attaching it to specific parameters only,pass any() instead,
    so instead of

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

    it becomes

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

    but it only works by adding In test setUpAll this line for custom classes

    registerFallbackValue(ChangeCardStatusRequest());
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search