Reputation: 1151
I'm trying to write a test for a function that configures a Dio instance to accept all SSL certificates, including those that are invalid or self-signed.
I have the following extension on Dio:
extension SSLExtension on Dio {
void enableUnknownCertificates() {
httpClientAdapter = IOHttpClientAdapter(
createHttpClient: () {
final HttpClient client = HttpClient(
context: SecurityContext(withTrustedRoots: false),
);
client.badCertificateCallback = ((_, __, ___) => true);
return client;
},
);
}
}
In my test, I want to verify that:
However, I'm struggling to mock or stub the HttpClient inside IOHttpClientAdapter. When I try to test it, I encounter issues like:
Here’s the test I attempted (it's working):
class MockDioAdapter extends Mock implements IOHttpClientAdapter {}
class MockHttpClient extends Mock implements HttpClient {
dynamic _badCertificateCallback;
MockHttpClient({SecurityContext? context});
@override
set badCertificateCallback(dynamic callback) {
print("badCertificateCallback assigned");
_badCertificateCallback = callback;
}
bool callBadCertificateCallback(
X509Certificate? cert, String host, int port) {
return _badCertificateCallback != null
? _badCertificateCallback(cert, host, port)
: false;
}
}
Test Function:
@GenerateMocks([Dio])
main() {
group('SSLExtension', () {
late MockDio dio;
late MockHttpClient mockHttpClient;
setUp(() {
dio = MockDio();
mockHttpClient = MockHttpClient(context: SecurityContext(withTrustedRoots: false));
mockHttpClient.badCertificateCallback = ((_, __, ___) => true);
});
test('enableUnknownCertificates should configure badCertificateCallback', () {
// Arrange
when(dio.httpClientAdapter).thenReturn(
IOHttpClientAdapter(
createHttpClient: () {
return mockHttpClient;
},
),
);
// Execute
dio.enableUnknownCertificates();
// Assert
expect(dio.httpClientAdapter, isA<IOHttpClientAdapter>());
expect(dio.httpClientAdapter, isNotNull);
final adapter = dio.httpClientAdapter as IOHttpClientAdapter;
final createHttpClient = adapter.createHttpClient;
expect(createHttpClient, isNotNull);
final client = createHttpClient!();
expect(client, isNotNull);
final result = mockHttpClient.callBadCertificateCallback(null, 'example.com', 443);
expect(result, true);
});
});
}
However, I haven't been able to achieve full branch coverage for the client creation execution in my test. This part is missing:
final HttpClient client = HttpClient(
context: SecurityContext(withTrustedRoots: false),
);
client.badCertificateCallback = ((_, __, ___) => true);
What is the best way to properly test the badCertificateCallback
and SecurityContext
setup in HttpClient
? Should I mock HttpClient differently, or is there a better approach?
Upvotes: 0
Views: 25