Friends
I am building flutter code that is centred around API calls made with the package http
To do integration tests and widget tests I have to mock calls that use http.Client
For my testing I wish to change as little of my application code as I can. If it were up to me I would not mock the API calls, but the flutter testing framework will not allow that. If there is a way to tell the flutter testing framework to allow me access to the network that would obviate my need for this question.
The methods to do what I am trying to do that I have found (e.g: here, and here) all involve modifying my application code. I am not going to modify application code, that works, to test it. That is putting the cart before the horse.
I have found this that includes code do do what I want with the package path_provider
.
Essentially
test("Test mocking path_provider", () async {
TestWidgetsFlutterBinding.ensureInitialized();
const MethodChannel channelPathProvider =
MethodChannel('plugins.flutter.io/path_provider');
channelPathProvider.setMockMethodCallHandler((MethodCall methodCall) async {
return "."; // <-- Breakpoint here. This is called
});
Directory dir = await getApplicationDocumentsDirectory();
print("dir: $dir");
});
This works well, and is what I need, but for a different package.
I copied the code as faithfully as I can (making some guesses I will detail after) and it does not do what I need. I am doing something incorrect:
test("Test mocking http", () async {
TestWidgetsFlutterBinding.ensureInitialized();
const MethodChannel channelPathProvider =
MethodChannel('plugins.flutter.io/http');
channelPathProvider.setMockMethodCallHandler((MethodCall methodCall) async {
return Response("Body", 200); // <-- Break point here. Not called
});
var client = Client();
Uri url = Uri.parse("https://example.com/");
Map<String, String> headers = <String, String>{
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"Accept": "application/json, text/javascript, */*; q=0.01",
};
var response =
await client.post(url, headers: headers, body: '{"foo":"bar"}');
print("response: $response Status: ${response.statusCode}");
});
}
My guesses were two:
- The argument to:
MethodChannel('plugins.flutter.io/http');
I see this all over, but i have seen no explanation of how the argument string 'plugins.flutter.io/http' is built. What I am doing seems logical - The mocked method call. In the
path_provider
example it returns ".". The call is expecting a Directory. That takes a string as a constructor, so??? I returnResult("body", 200)
. If the mocked function were being called, this might be a problem. But it is not so is not, yet.