Comments (16)
Hi @tazik561 !
The problem is you're throwing a AdapterError
as expected value:
expect(() async => await dio.post(path), throwsA(isA<AdapterError>()));
But you was given a DioError
into dioAdapterMockito.onPost
method:
dioAdapterMockito.onPost(
path,
(request) => request.throws(500, dioError),
headers: {'Content-Type': 'application/json; charset=utf-8'},
);
So I mean you should change your expected value as DioError
, like:
expect(() async => await dio.post(path), throwsA(isA< DioError>()));
The full test code:
Note: I am using the latest version of the packages
void main() {
group("Splash init", () {
DioAdapterMockito dioAdapterMockito;
Dio dio;
const path = 'https://..../mobile/';
setUpAll(() {
dioAdapterMockito = DioAdapterMockito();
dio = Dio()..httpClientAdapter = dioAdapterMockito;
});
test(
"call getMainConfigs -> getMainConfig web service called 404 exception",
() async {
final dioError = DioError(
error: {'message': 'Some beautiful error!'},
requestOptions: RequestOptions(path: path),
response: Response(
statusCode: 500,
requestOptions: RequestOptions(path: path),
),
type: DioErrorType.response,
);
dioAdapterMockito.onPost(
path,
(request) => request.throws(500, dioError),
headers: {'Content-Type': 'application/json; charset=utf-8'},
);
expect(() async => await dio.post(path), throwsA(isA<AdapterError>()));
// expect(() async => await dio.get(path), throwsA(isA<DioError>()));
// expect(
// () async => await dio.get(path),
// throwsA(
// predicate(
// (DioError error) =>
// error is DioError &&
// error is AdapterError &&
// error.message == dioError.error.toString(),
// ),
// ),
// );
});
});
}
Correct and clean usage of http-mock-adapter should be:
void main() {
DioAdapter dioAdapterMockito;
Dio dio;
DioError dioError;
const path = 'https://example.com';
setUpAll(() {
dioAdapterMockito = DioAdapterMockito();
dio = Dio();
dio.httpClientAdapter = dioAdapterMockito;
DioError(
error: {'message': 'Some beautiful error!'},
requestOptions: RequestOptions(path: path),
response: Response(
statusCode: 500,
requestOptions: RequestOptions(path: path),
),
type: DioErrorType.response,
);
});
group("Splash init", () {
test(
"call getMainConfigs -> getMainConfig web service called 404 exception",
() async {
dioAdapterMockito.onPost(
path,
(request) => request.throws(500, dioError),
headers: {'Content-Type': 'application/json; charset=utf-8'},
);
expect(() async => await dio.post(path), throwsA(isA<DioError>()));
});
});
}
from http-mock-adapter.
@tazik561 are you using the latest version of http_mock_adapter?
from http-mock-adapter.
@LukaGiorgadze no Luka, we were resolved this issue with #100 PR. @tazik561 's issue needn't any changes on http-mock-adapter, he just should do this , so the problem is his test code.
from http-mock-adapter.
Hi @tazik561
I tried fix your problem by initializingdio: ^3.0.9
andhttp_mock_adapter: ^0.1.6
.
And I fixed it, It's simple you just need to change your expected value to:expect(() async => await dio.post(path), throwsA(isA<DioError>()));Just that, and I said that in this answer.
I don't want to test dio directly . As I mention above I have a method called : getConcreteNumberTrivia
.
Future<NumberTriviaModel> getConcreteNumberTrivia(String url) async {
final response =
await dio.get(url, headers: {'Content-Type': 'application/json'});
if (response.statusCode == 200) {
return NumberTriviaModel.fromJson(json.decode(response.body));
} else {
throw ServerExceptions();
}
}
I am trying write test for this method getConcreteNumberTrivia
. Inside this method there is a dio .Now I want when parser rich to dio, dio throw an error or exception .
In this answer we just test dio directly. But I want to test a method that has dio part like repository layer.
for example
setupMockHttpClientFailure404(){
dioAdapterMockito.onPost(
path,
(request) => request.throws(404, dioError),
headers: {'Content-Type': 'application/json; charset=utf-8'},
);
}
test(
'should throw a ServerException when the responce code is 404 or other ',
() async {
setupMockHttpClientFailure404();
final call = dataSource.getConcreteNumberTrivia;
expect(call(url), throwsA(TypeMatcher<ServerExceptions>()));
},
);
I call final call = dataSource.getConcreteNumberTrivia;
in test, In getConcreteNumberTrivia
method when parser rich to final response = await dio.get(url, headers: {'Content-Type': 'application/json'});
, throw an exception.
from http-mock-adapter.
Well, I'm trying to use this with get_it
. I register my client with:
getIt.registerLazySingleton(
() => BaseOptions(baseUrl: 'https://www.bscotch.net/api/levelhead'),
instanceName: 'rumpusClientBaseOptions');
getIt.registerLazySingleton(
() => Dio(getIt.get(instanceName: 'rumpusClientBaseOptions')),
instanceName: 'rumpusClient');
Then in setUpAll
, I do:
setUpAll(() async {
await setUpDI();
var adapter = DioAdapter();
adapter
..onGet(
'/players',
(request) => request.reply(200, {
'data': [
{
"_id": "609e5516f0b9d200b711b8b5",
"userId": "pvdw78",
"stats": {
"Subscribers": 0,
"NumFollowing": 0,
"Crowns": 0,
"Shoes": 0,
"PlayTime": 0,
"TipsPerLevel": 0,
"TipsPerDay": 0,
"TippedPerLevelPlayed": 0,
"TippedPerDay": 0,
"HiddenGem": 0,
"Trophies": 0,
"PerkPoints": 5,
"CampaignProg": 0,
"TimeTrophies": 0
},
"createdAt": "2021-05-14T10:46:46.723Z",
"updatedAt": "2021-05-14T10:46:48.639Z",
"alias": {
"userId": "pvdw78",
"alias": "LeapyimbleZiprompa",
"avatarId": "gr18-serious",
"context": "levelhead"
}
}
]
}));
Dio client = getIt.get(instanceName: 'rumpusClient');
client.httpClientAdapter = adapter;
});
Since it is a lazy singleton, I'm sure I get the only one instance of Dio
. I change the adapter to this mock adapter as you can see above. However, running my tests, I get the error saying:
DioError [DioErrorType.other]: Assertion failed: "Could not find mocked route matching request for /players/GET/null/{includeRecords: true, includeStats: true, userIds: foobar}/{}"
Opting out of baseUrl
also does no good.
Environment
> flutter --version
Flutter 2.0.5 • channel stable • https://github.com/flutter/flutter.git
Framework • revision adc687823a (4 weeks ago) • 2021-04-16 09:40:20 -0700
Engine • revision b09f014e96
Tools • Dart 2.12.3
- dio 4.0.0
- http_mock_adapter 0.2.1
from http-mock-adapter.
I have had several cases where the mocked route could not be found. It was always my mistake but it is hard to trace down with the current assertion errors. I suggest we introduce a custom error messages with diffs for data/headers/params, especially if there is only one mocked response. With more than one mocked response it might get a bit harder to generate a correct diff.
from http-mock-adapter.
Hi @tazik561 !
The problem is you're throwing a
AdapterError
as expected value:expect(() async => await dio.post(path), throwsA(isA<AdapterError>()));But you was given a
DioError
intodioAdapterMockito.onPost
method:dioAdapterMockito.onPost( path, (request) => request.throws(500, dioError), headers: {'Content-Type': 'application/json; charset=utf-8'}, );So I mean you should change your expected value as
DioError
, like:expect(() async => await dio.post(path), throwsA(isA<AdapterError>()));The full test code:
Note: I am using the latest version of the packagesvoid main() { group("Splash init", () { DioAdapterMockito dioAdapterMockito; Dio dio; const path = 'https://..../mobile/'; setUpAll(() { dioAdapterMockito = DioAdapterMockito(); dio = Dio()..httpClientAdapter = dioAdapterMockito; }); test( "call getMainConfigs -> getMainConfig web service called 404 exception", () async { final dioError = DioError( error: {'message': 'Some beautiful error!'}, requestOptions: RequestOptions(path: path), response: Response( statusCode: 500, requestOptions: RequestOptions(path: path), ), type: DioErrorType.response, ); dioAdapterMockito.onPost( path, (request) => request.throws(500, dioError), headers: {'Content-Type': 'application/json; charset=utf-8'}, ); expect(() async => await dio.post(path), throwsA(isA<AdapterError>())); // expect(() async => await dio.get(path), throwsA(isA<DioError>())); // expect( // () async => await dio.get(path), // throwsA( // predicate( // (DioError error) => // error is DioError && // error is AdapterError && // error.message == dioError.error.toString(), // ), // ), // ); }); }); }Correct and clean use of http-mock-adapter should be:
void main() { DioAdapter dioAdapterMockito; Dio dio; DioError dioError; const path = 'https://example.com'; setUpAll(() { dioAdapterMockito = DioAdapterMockito(); dio = Dio(); dio.httpClientAdapter = dioAdapterMockito; DioError( error: {'message': 'Some beautiful error!'}, requestOptions: RequestOptions(path: path), response: Response( statusCode: 500, requestOptions: RequestOptions(path: path), ), type: DioErrorType.response, ); }); group("Splash init", () { test( "call getMainConfigs -> getMainConfig web service called 404 exception", () async { dioAdapterMockito.onPost( path, (request) => request.throws(500, dioError), headers: {'Content-Type': 'application/json; charset=utf-8'}, ); expect(() async => await dio.post(path), throwsA(isA<DioError>())); }); }); }
Thank . I changed my code to this:
group("Dio Exception", () {
DioAdapterMockito dioAdapterMockito;
Dio dio;
DioError dioError;
const path = 'https://..../mobile/';
setUpAll(() {
dioAdapterMockito = DioAdapterMockito();
dio = Dio()..httpClientAdapter = dioAdapterMockito;
dioError = DioError(
error: {'message': 'Some beautiful error!'},
request: RequestOptions(
path: path,
),
response: Response(
statusCode: 500,
request: RequestOptions(path: path),
),
type: DioErrorType.RESPONSE,
);
});
test(
"call getMainConfigs -> getMainConfig web service called 404 exception",
() async {
dioAdapterMockito.onPost(
path,
(request) => request.throws(500, dioError),
headers: {'Content-Type': 'application/json; charset=utf-8'},
);
var result = await dio.post(path, data: null);
expect(() async => result, throwsA(isA<DioError>()));
});
});
}
But I got this error:
DioError [DioErrorType.DEFAULT]: NoSuchMethodError: The getter 'headers' was called on null.
Receiver: null
Tried calling: headers
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:54:5)
#1 DioMixin._dispatchRequest
package:dio/src/dio.dart:927
<asynchronous suspension>
#2 StackZoneSpecification._registerUnaryCallback.<anonymous closure> (package:stack_trace/src/stack_zone_specification.dart)
package:stack_trace/src/stack_zone_specification.dart:1
<asynchronous suspension>
2
DioMixin._dispatchRequest
package:dio/src/dio.dart:966
from http-mock-adapter.
Don't create a variable for await dio.post()
just write it directly.
However expect method should be:
expect(() async => await dio.post(path, data: null),
throwsA(isA<DioError>()));
Not this:
var result = await dio.post(path, data: null);
expect(() async => result, throwsA(isA<DioError>()));
And make sure you're using latest versions of dio
and http_mock_adapter
.
Here is the full code of your test:
group("Dio Exception", () {
DioAdapterMockito dioAdapterMockito;
Dio dio;
DioError dioError;
const path = 'https://..../mobile/';
setUpAll(() {
dioAdapterMockito = DioAdapterMockito();
dio = Dio()..httpClientAdapter = dioAdapterMockito;
dioError = DioError(
error: {'message': 'Some beautiful error!'},
requestOptions: RequestOptions(path: path),
response: Response(
statusCode: 500,
requestOptions: RequestOptions(path: path),
),
type: DioErrorType.response,
);
});
test(
"call getMainConfigs -> getMainConfig web service called 404 exception",
() async {
dioAdapterMockito.onPost(
path,
(request) => request.throws(500, dioError),
headers: {'Content-Type': 'application/json; charset=utf-8'},
);
expect(() async => await dio.post(path, data: null),
throwsA(isA<DioError>()));
});
});
from http-mock-adapter.
Of course not. I am using dio: ^3.0.9
and http_mock_adapter: ^0.1.6
because I don't use sounds null safety environment: sdk: ">=2.7.0 <3.0.0"
.
It is possible to mix DioAdapterMockito in this way ):
setupMockHttpClientFailure404(){
dioAdapterMockito.onPost(
path,
(request) => request.throws(404, dioError),
headers: {'Content-Type': 'application/json; charset=utf-8'},
);
}
test(
'should throw a ServerException when the responce code is 404 or other ',
() async {
setupMockHttpClientFailure404();
final call = dataSource.getConcreteNumberTrivia;
expect(call(url), throwsA(TypeMatcher<ServerExceptions>()));
},
);
main method on repo class:
Future<NumberTriviaModel> getConcreteNumberTrivia(String url) async {
final response =
await dio.get(url, headers: {'Content-Type': 'application/json'});
if (response.statusCode == 200) {
return NumberTriviaModel.fromJson(json.decode(response.body));
} else {
throw ServerExceptions();
}
}
to check a method that has dio method inside it?
from http-mock-adapter.
Hi @tazik561
I tried fix your problem by initializing dio: ^3.0.9
and http_mock_adapter: ^0.1.6
.
And I fixed it, It's simple you just need to change your expected value to:
expect(() async => await dio.post(path), throwsA(isA<DioError>()));
Just that, and I said that in this answer.
from http-mock-adapter.
@theiskaa i guess we resolved this in #100 PR, right?
from http-mock-adapter.
same problem here
from http-mock-adapter.
Hi @erayerdin first of all thanks for your response!
In your test code I can see you did mocking some request by this path:
/players/GET/{your data here}/{includeRecords: true, includeStats: true, userIds: foobar}/{}
and you get error by this path:
/players/GET/null/{includeRecords: true, includeStats: true, userIds: foobar}/{}
So your test code's path and real code's path are different.
However in your real code you didn't give data and that's why your data's place is null.
Just try giving same data, path and variables, if something goes wrong please tell us, write down in this issue or fill a new one.
from http-mock-adapter.
Hi @tazik561
I tried fix your problem by initializingdio: ^3.0.9
andhttp_mock_adapter: ^0.1.6
.
And I fixed it, It's simple you just need to change your expected value to:expect(() async => await dio.post(path), throwsA(isA<DioError>()));Just that, and I said that in this answer.
I don't want to test dio directly . As I mention above I have a method called :
getConcreteNumberTrivia
.Future<NumberTriviaModel> getConcreteNumberTrivia(String url) async { final response = await dio.get(url, headers: {'Content-Type': 'application/json'}); if (response.statusCode == 200) { return NumberTriviaModel.fromJson(json.decode(response.body)); } else { throw ServerExceptions(); } }
I am trying write test for this method
getConcreteNumberTrivia
. Inside this method there is a dio .Now I want when parser rich to dio, dio throw an error or exception .In this answer we just test dio directly. But I want to test a method that has dio part like repository layer.
for example
setupMockHttpClientFailure404(){ dioAdapterMockito.onPost( path, (request) => request.throws(404, dioError), headers: {'Content-Type': 'application/json; charset=utf-8'}, ); } test( 'should throw a ServerException when the responce code is 404 or other ', () async { setupMockHttpClientFailure404(); final call = dataSource.getConcreteNumberTrivia; expect(call(url), throwsA(TypeMatcher<ServerExceptions>())); }, );
I call
final call = dataSource.getConcreteNumberTrivia;
in test, IngetConcreteNumberTrivia
method when parser rich tofinal response = await dio.get(url, headers: {'Content-Type': 'application/json'});
, throw an exception.
@tazik561 Okay, as I understand it, you have a dio
and that one isn't into your method right? So you wanna test your method, then you shouldn't test dio
directly, yeah that is correct. But it's interesting where you do set dio
class? you have to do same thing what are you doing when you are testing dio directly. Just set you dio's httpClientAdapter and go on!
from http-mock-adapter.
Hi guys! I'm trying to solve this and there is no way!
I have this class:
import 'dart:io';
import 'package:dio/dio.dart';
/// Dio requests types
enum Method {
/// post
post,
/// get
get,
/// put
put,
/// delete
delete,
/// patch
patch,
}
/// {@template http_service}
/// A service for managing requests
/// {@endtemplate}
class HttpService {
/// {@macro http_service}
HttpService({
required Dio httpClient,
}) : _httpClient = httpClient {
init(httpClient: _httpClient);
}
late Dio _httpClient;
/// service initialization and configuration
Future<HttpService> init({
required Dio httpClient,
}) async {
_httpClient = httpClient;
return this;
}
/// help in handling request methods
Future<Response> request({
required String endpoint,
required Method method,
Map<String, dynamic>? params,
}) async {
Response response;
try {
if (method == Method.post) {
response = await _httpClient.post<dynamic>(endpoint, data: params);
} else if (method == Method.delete) {
response = await _httpClient.delete<dynamic>(endpoint);
} else if (method == Method.patch) {
response = await _httpClient.patch<dynamic>(endpoint);
} else {
response =
await _httpClient.get<dynamic>(endpoint, queryParameters: params);
}
if (response.statusCode == 200) {
return response;
} else if (response.statusCode == 401) {
throw Exception('Unauthorized');
} else if (response.statusCode == 500) {
throw Exception('Server Error');
} else {
throw Exception("Something does wen't wrong");
}
} on SocketException catch (e) {
throw Exception('Not Internet Connection');
} on FormatException catch (e) {
throw Exception('Bad response format');
} on DioError catch (e) {
throw Exception(e);
} catch (e) {
throw Exception("Something wen't wrong");
}
}
}
And trying to test errors and exceptions with this:
test('should return a Server Error Exception', () async {
dioAdapter.onPost(
'/endpoint',
(server) => server.throws(500, Constants.dioError),
data: <String, dynamic>{},
headers: Constants.edamamPostHeader,
);
expect(
() async => await httpService.request(
endpoint: '/endpoint',
method: Method.post,
params: <String, dynamic>{},
),
isA<DioError>,
);
});
But could not resolve correctly the expectation:
Expected: <Closure: () => TypeMatcher<DioError> from Function 'isA': static.>
Actual: <Closure: () => Future<Response<dynamic>>>
Any thoughts? Thanks in advance!
from http-mock-adapter.
I did this which I think is correct. What do you think?
from http-mock-adapter.
Related Issues (20)
- route matches ignore `baseUrl`
- Selective mocking HOT 11
- can i request to onDownload when add unit test ? HOT 2
- [v0.4.0] collection version conflict between the v0.4.0 and flutter_test HOT 9
- Lower the Dart SDK constraint to 2.15.0
- Let server return different responses HOT 7
- FullHttpRequestMatcher: not identical data returns success response HOT 3
- Using query parameters in response data generation HOT 2
- use tester.pump rather than Future.delayed to allow tests to run faster HOT 1
- Split up `MockServer` `reply` method into static and dynamic version HOT 11
- http_mock_adapter 0.5.0 conflicts with flutter_test collection version. HOT 8
- Async mocking not possible HOT 1
- Semantic release with github action HOT 2
- Add methods onDownload & onDownloadUri
- Library not compatible with flutter 3.16.0 - incorrect type definition HOT 3
- LDClient.get() was called before init()!
- Ability to mock whole API interface for local development without a need of a server. HOT 2
- Allow timeout simulations in replies HOT 2
- QUESTION: how to use dio.simpleGet HOT 2
- http_mock_adapter-0.4.4/lib/src/mixins/request_handling.dart:32:42: Error: A value of type 'FutureOr<List<int>>' can't be assigned to a variable of type 'List<int>'. HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from http-mock-adapter.