Eyder Rios
Eyder Rios

Reputation: 11

Mocktail error: No method stub was called from within `when()`

I'm using mocktail 0.3.0 package to test the request() method from HttpAdapter class. This method should call post() method of the Client class of the http package.

class HttpAdapter {
  static const headers = {
    HttpHeaders.contentTypeHeader: 'application/json',
    HttpHeaders.acceptHeader: 'application/json',
  };

  final Client client;

  HttpAdapter(this.client);

  Future<void> request({
    required String url,
    required String method,
    HttpClientBody? body,
  }) async {
    await client.post(Uri.parse(url), headers: HttpAdapter.headers);
  }
}

class ClientSpy extends Mock implements Client {
  void mockPost(String url) {
    when(() => post(
          Uri.parse(url),
          headers: any(named: 'headers'),
        )).thenAnswer(
      (_) async => Response('{}', HttpStatus.ok),
    );
  }
}

When I test using the code below, everything goes well:

void main() {
 test('Should call post() with correct parameters', () async {
   // Arrange
   final client = ClientSpy();
   final sut = HttpAdapter(client);

   when(() => client.post(
         Uri.parse(url),
         headers: HttpAdapter.headers,
       )).thenAnswer(
     (_) async => Response('{}', HttpStatus.ok),
   );
   // Act
   await sut.request(url: url, method: method);
   // Assert
   verify(() => client.post(
         Uri.parse(url),
         headers: HttpAdapter.headers,
       ));
  });
}

But if I replace the when() instruction by mockPost() method I get the error: Bad state: No method stub was called from within 'when()'. Was a real method called, or perhaps an extension method?

void main() {
 test('Should call post() with correct parameters', () async {
   // Arrange
   final client = ClientSpy();
   final sut = HttpAdapter(client);

   client.mockPost();
   // Act
   await sut.request(url: url, method: method);
   // Assert
   verify(() => client.post(
         Uri.parse(url),
         headers: HttpAdapter.headers,
       ));
  });
}

What am I doing wrong?

Upvotes: 0

Views: 528

Answers (1)

Eyder Rios
Eyder Rios

Reputation: 11

I think I figured out the problem.

The ClientSpy class implements the Client class from http package. The Client class has a method called post(), witch is the one I want to call. However, http package has a post() function also (I did't know that). So, I was calling the post() function instead Client.post() method.

The code below is working fine now:

class ClientSpy extends Mock implements Client {
  void mockPost(String url) {
    when(() => this.post(
          Uri.parse(url),
          headers: any(named: 'headers'),
        )).thenAnswer(
      (_) async => Response('{}', HttpStatus.ok),
    );
  }
}

or

import 'package:http/http.dart' as http;

class ClientSpy extends Mock implements http.Client {
  void mockPost(String url) {
    when(() => post(
          Uri.parse(url),
          headers: any(named: 'headers'),
        )).thenAnswer(
      (_) async => Response('{}', HttpStatus.ok),
    );
  }
}

Upvotes: 1

Related Questions