HTTP requests mocking library for dart and flutter.
Nock can be used to test modules that perform HTTP requests in isolation.
Inspired by nock
Add dev dependency to your pubspec.yaml
:
dev_dependencies:
nock: ^1.2.3
import 'package:test/test.dart';
import 'package:http/http.dart' as http;
import 'package:nock/nock.dart';
void main() {
setUpAll(() {
nock.init();
});
setUp(() {
nock.cleanAll();
});
test("example", () async {
final interceptor = nock("http://localhost/api").get("/users")
..reply(
200,
"result",
);
final response = await http.get("http://localhost/api/users");
expect(interceptor.isDone, true);
expect(response.statusCode, 200);
expect(response.body, "result");
});
}
if some request isn't mocked NetConnectionNotAllowed
exception will be thrown:
void main() {
test("example", () async {
expect(
http.get("http://localhost/api/users"),
throwsA(TypeMatcher<NetConnectionNotAllowed>()),
);
});
}
final String baseUrl = "https://my-server.com";
final scope = nock(baseUrl);
scope.get(dynamic url)
-> Interceptorscope.post(dynamic url, dynamic body)
-> Interceptorscope.put(dynamic url, dynamic body)
-> Interceptorscope.delete(dynamic url, dynamic body)
-> Interceptorscope.patch(dynamic url, dynamic body)
-> Interceptorscope.head(dynamic url, dynamic body)
-> Interceptor
You could specify baseUrl
for automatic scope usage:
void main(){
setUpAll((){
nock.defaultBase = "http://localhost/api";
nock.init();
});
test("example", () async {
nock.get("/users"); // create mock for GET http://localhost/api/users
});
}
You could use strings, regexp or any matcher from package:test:
final topicsInterceptor = nock.get("/topics")
..reply(200);
final usersInterceptor = nock.get(startsWith("/users"))
..reply(200);
final tagsInterceptor = nock.get(RegExp(r"^/tags$"))
..reply(200);
final interceptor = nock.get("/users")
..headers({
'Session-Token': '59aff48f-369e-4781-a142-b52666cf141f',
})
..reply(200);
Using query string:
final interceptor = nock.get("/users")
..query("ids[]=1&ids[]=2")
..reply(200);
Using example:
final interceptor = nock.get("/users")
..query({"id": 5})
..reply(200);
Using matchers:
final interceptor = nock.get("/users")
..query(startsWith("something"))
..reply(200);
final interceptor = nock.get("/users")
..query({'id': anyOf([1, 2, 3])})
..reply(200);
Using custom match function:
final interceptor = nock.get("/users")
..query((Map<String, List<String>> params) => true)
..reply(200);
// or
final interceptor = nock.get("/users")
..query((Map<String, String> params) => true)
..reply(200);
Interceptor will parse HTTP request headers and try parse body.
Supported mime-types:
application/x-www-form-urlencoded
application/json
application/text
application/text
Using example:
final interceptor = nock.post(
"/users",
{
"name": "John",
"email": "[email protected]",
},
)
..reply(204);
Using matchers:
final interceptor = nock.post(
"/users",
{
id: anyOf([1, 2, 3])
name: any,
email: TypedMather<String>(),
},
)
..reply(204);
Using custom match function:
final interceptor = nock.post(
"/users",
(body) => body is Map,
)
..reply(204);
If you send binary data you could use custom raw match function:
final interceptor = nock.post(
"/users",
(List<int> body) => true,
)
..reply(204);
application/json:
final interceptor = nock.get("/users")
..reply(200, [
{
"id": 1,
"name": "John",
"email": "[email protected]",
},
{
"id": 2,
"name": "Mark",
"email": "[email protected]",
},
]);
text/plain:
final interceptor = nock.get("/ping")
..reply(200, "pong");
Other binary data:
final interceptor = nock.get("/video")
..reply(200, <int>[73, 32, 97, 109, 32, 118, 105, 100, 101, 111]);
Other binary data:
final interceptor = nock.get("/auth")
..reply(204, null, {
"Session-Token": "59aff48f-369e-4781-a142-b52666cf141f",
});
To repeat responses for as long as nock is active, use .persist()
.
final users = nock.get("/users")
..persist()
..reply(
200,
"result",
);
Note that while a persisted mock will always intercept the requests, it is considered "done" after the first interception.
Canceling pending mock:
users.cancel();
final users = nock.get("/users")
..persist()
..reply(
200,
"result",
)
..onReply(() => print("I'm done"));
Feel free to open PR or an issue