cah4a / dart_nock Goto Github PK
View Code? Open in Web Editor NEWHTTP requests mocking library for dart and flutter.
Home Page: https://pub.dev/packages/nock
License: MIT License
HTTP requests mocking library for dart and flutter.
Home Page: https://pub.dev/packages/nock
License: MIT License
Hi @cah4a! hope you are doing well.
I was wondering if the package will get null safety support? I have a package that depends on nock but I have not yet been able to migrate it.
๐
Like mentioned in title, POST requests with body specified result in exception.
I'm on nock 1.2.0
Below is the reproduction code:
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("GET", () async {
final interceptor = nock("http://localhost/api").get("/users")
..reply(
200,
"result",
);
final response = await http.get(Uri.parse("http://localhost/api/users"));
expect(interceptor.isDone, true);
expect(response.statusCode, 200);
expect(response.body, "result");
});
test("POST without body", () async {
final interceptor = nock("http://localhost/api").post("/users")
..reply(
200,
"result",
);
final response = await http.post(Uri.parse("http://localhost/api/users"));
expect(interceptor.isDone, true);
expect(response.statusCode, 200);
expect(response.body, "result");
});
test("POST with body - DOESN'T WORK", () async {
final interceptor = nock("http://localhost/api").post("/users")
..reply(
200,
"result",
);
final response = await http.post(Uri.parse("http://localhost/api/users"), body: "{}");
expect(interceptor.isDone, true);
expect(response.statusCode, 200);
expect(response.body, "result");
});
}
When using this library with Flutter 3, it fails with this error:
../../../../.pub-cache/hosted/pub.dartlang.org/nock-1.2.0/lib/src/overrides.dart:20:7: Error: The non-abstract class 'MockClient' is missing implementations for these members:
- HttpClient.connectionFactory=
- HttpClient.keyLog=
Try to either
- provide an implementation,
- inherit an implementation from a superclass or mixin,
- mark the class as abstract, or
- provide a 'noSuchMethod' implementation.
class MockClient implements HttpClient {
^^^^^^^^^^
../../../../flutter/bin/cache/dart-sdk/lib/_http/http.dart:1554:12: Context: 'HttpClient.connectionFactory=' is defined here.
void set connectionFactory(
^^^^^^^^^^^^^^^^^
../../../../flutter/bin/cache/dart-sdk/lib/_http/http.dart:1704:12: Context: 'HttpClient.keyLog=' is defined here.
void set keyLog(Function(String line)? callback);
^^^^^^
We can use query, in which, using params, we can perform the necessary actions.
interceptor = nock(baseurl).get(dynamicPath)
..query((params) => true)...
But what if I need to check it by path params (https://myUrl/myParam )? Is it possible to access the intercepted url?
Hey there, great work with Nock. It works pretty awesome so far! I've stumbled on the first problem when I started (m/n)ocking my first POST request. I can't seem to get it to Mock the request correct.
I'm using Nock 1.0.2 using the Flutter test environment.
The minimum code to replicate this issue is as follows:
The class
import 'package:http/http.dart';
class TestClass {
Future<bool> postTest() async {
String url = 'https://example.com/awesome';
Response response = await Client().post(url, headers: {"Content-type": "application/json"}, body: jsonEncode({"some": "data"}));
if(response.statusCode == 200) {
return true;
} else {
throw("${response.statusCode}: eror request");
}
}
}
In the testfile:
setUpAll(() {
nock.init();
});
setUp(() {
nock.cleanAll();
});
final testClass = TestClass();
test('should work', () async {
final interceptor = nock("https://example.com").post("/awesome",
{"some": "data"}
)..headers( {"Content-type": "application/json"})
..replay(200, {"test": "test"});
var result = await testClass.postTest();
expect(result, true);
expect(interceptor.isDone, true);
});
Result:
should work:
ERROR: Request was: POST https://example.com/awesome
Pending mocks: (post https://example.com/awesome +b -> 200 {test: test})
package:nock/src/overrides.dart 146:7 MockHttpClientRequest.done
package:nock/src/overrides.dart 181:41 MockHttpClientRequest.close
dart:async _completeOnAsyncReturn
package:nock/src/overrides.dart MockHttpClientRequest.addStream
What I tried:
I'm working on a module which checks the head
s of uris before deciding which to get
. I've been able to create both the get
and head
interceptors in Nock, as follows:
nock.head ('hello.txt')..reply (200, null, headers {...});
nock.get ('hello.txt).. reply (200, "Hello world!", headers {...});
But I'm constantly forgetting to add the heads!
It would be great if I could either set a flag to auto-generate the head
s (so I didn't need to specify them) or write a single rule to translate every head
interceptor into the corresponding get
.
Any ideas? Thanks.
Hey, I recently upgraded my (older) flutter app and all of its dependencies - including http from 0.12.2 to 0.13.4 (latest version).
Since that upgrade I get the following errors while running tests with [email protected]
./../.pub-cache/hosted/pub.dartlang.org/nock-1.2.0/lib/src/overrides.dart:20:7: Error: The non-abstract class 'MockClient' is missing implementations for these members:
- HttpClient.connectionFactory=
- HttpClient.keyLog=
Try to either
- provide an implementation,
- inherit an implementation from a superclass or mixin,
- mark the class as abstract, or
- provide a 'noSuchMethod' implementation.
class MockClient implements HttpClient {
^^^^^^^^^^
org-dartlang-sdk:///third_party/dart/sdk/lib/_http/http.dart:1554:12: Context: 'HttpClient.connectionFactory=' is defined here.
void set connectionFactory(
^^^^^^^^^^^^^^^^^
org-dartlang-sdk:///third_party/dart/sdk/lib/_http/http.dart:1704:12: Context: 'HttpClient.keyLog=' is defined here.
void set keyLog(Function(String line)? callback);
PS: is the package still actively maintained?
HI, I recently upgraded my flutter version and all of its dependencies - including nock from 1.2.1 to 1.2.2 (latest version).
Since that upgrade I get the following errors while running tests with [email protected]
[+1496 ms] Compiler message: [ +2 ms] ../../flutter/.pub-cache/hosted/pub.dartlang.org/nock-1.0.1/lib/src/http_headers.dart:53:8: Error: The method 'MockHttpHeaders.add' has fewer named arguments than those of overridden method 'HttpHeaders.add'. [ ] void add(String name, value) { [ ] ^ [ ] org-dartlang-sdk:///third_party/dart/sdk/lib/_http/http.dart:695:8: Context: This is the overridden method ('add'). [ ] void add(String name, Object value, [ ] ^ [ +1 ms] ../../flutter/.pub-cache/hosted/pub.dartlang.org/nock-1.0.1/lib/src/http_headers.dart:69:3: Error: The method 'MockHttpHeaders.set' has fewer named arguments than those of overridden method 'HttpHeaders.set'. [ ] set(String name, Object value) { [ ] ^ [ ] org-dartlang-sdk:///third_party/dart/sdk/lib/_http/http.dart:704:8: Context: This is the overridden method ('set'). [ ] void set(String name, Object value, [ ] ^
First of all, thank you for the package, it works great!
I have two questions/improvement ideas regarding mocked responses.
Currently the replay()
function has body as required parameter. However the response body is not required in some cases: a 204 response or even with 201 etc. Could this be changed to an optional parameter? For now I provide null as the body and it seems to work okay.
Another question is also regarding the replay()
function. The original nock has the name as reply()
as in replying to a request I guess. I think replay sounds a bit weird here. How come this was changed?
Hi!
First, awesome work with nock, is so useful, thanks.
Everything is working great, but when I try to run tests with code coverage, fails. I have a couple of test files, one of those, use nock. To be more specific, the issue is when creating a single test file for group the coverage.
This is what I've tried so far:
pub run test
works without troubles.test_coverage
and test_cov
packages fails.pub run test --coverage ./coverage
works but create a file for every test and I need a single one.pub run test test/main_test.dart --coverage ./coverage
works but only when no nock test included or nock test is alone.This is the main_test.dart
file I'm using:
import 'basic_test.dart' as basic_test;
import 'nock_test.dart' as nock_test;
void main() {
basic_test.main();
nock_test.main();
}
Hi again @cah4a
I'm having troubles with mocking multiple requests. I have an Api class that performs a couple of requests but always is needed to be called the first()
method before the others because depends on the result.
The first request is called but the second is throwing a NetConnectionNotAllowed
with pending mocks. Here's the example I'm trying to run:
https://gist.github.com/pblinux/54a05e3b9afeac1cd37893550236f44f
Maybe I'm using nock in a wrong way?
Hi, Seems like nock.post() does not intercept http.post() call if http.post() contains 'headers'.
But. this is not problem with nock.get().
Can someone make example how use headers with interceptor? Or is that even possible?
Future<http.Response?> apiPostJson(
Map<String, dynamic> jsonPayload,
) async {
final fullUrl = 'http://localhost:3000/todos';
final payloadStr = json.encode(jsonPayload);
try {
final response = await http
.post(
Uri.parse(fullUrl),
headers: {
HttpHeaders.contentTypeHeader: 'application/json',
HttpHeaders.cacheControlHeader: 'no-cache'
},
body: payloadStr,
)
.timeout(
const Duration(seconds: 60),
onTimeout: () {
return http.Response('Error', 408); },
);
return response;
} on ClientException {
print('NO NETWORK');
}
return null;
}
// This test will fail:
test('headers', () async {
final url = 'http://localhost:3000';
final interceptor = nock(url).post(
'/todos',
json.encode({'text': 'jee', 'done': false}),
)..reply(
200,
{'result': true},
);
final result = await apiPostJson({'text': 'jee', 'done': false});
expect(interceptor.isDone, true);
expect(result, isNotNull);
});
Test result:
Request was: POST http://localhost:3000/todos
Pending mocks: (post http://localhost:3000/todos +b -> 200 {result: true})
package:nock/src/overrides.dart 172:7 MockHttpClientRequest.done
package:nock/src/overrides.dart 216:41 MockHttpClientRequest.close
And this fails also:
test('headers', () async {
final url = 'http://localhost:3000';
final interceptor = nock(url).post(
'/todos',
json.encode({'text': 'jee', 'done': false}),
)
..headers({
HttpHeaders.contentTypeHeader: 'application/json',
HttpHeaders.cacheControlHeader: 'no-cache'
})
..reply(
200,
{'result': true},
);
final result = await apiPostJson({'text': 'jee', 'done': false});
expect(interceptor.isDone, true);
expect(result, isNotNull);
});
With result:
Request was: POST http://localhost:3000/todos
Pending mocks: (post http://localhost:3000/todos +b -> 200 {result: true})
package:nock/src/overrides.dart 172:7 MockHttpClientRequest.done
package:nock/src/overrides.dart 216:41 MockHttpClientRequest.close
But without headers everything works:
Future<http.Response?> apiPostJson(
Map<String, dynamic> jsonPayload,
) async {
final fullUrl = 'http://localhost:3000/todos';
final payloadStr = json.encode(jsonPayload);
try {
final response = await http
.post(
Uri.parse(fullUrl),
body: payloadStr,
)
.timeout(
const Duration(seconds: 60),
onTimeout: () {
return http.Response('Error', 408);
},
);
return response;
} on ClientException {
print('NO NETWORK');
}
return null;
}
// Test will pass:
test('headers', () async {
final url = 'http://localhost:3000';
final interceptor = nock(url).post(
'/todos',
json.encode({'text': 'jee', 'done': false}),
)..reply(
200,
{'result': true},
);
final result = await apiPostJson({'text': 'jee', 'done': false});
expect(interceptor.isDone, true);
expect(result, isNotNull);
});
With result:
00:02 +7: All tests passed!
Is there a way to test timeouts by adding a delay to the reply, i.e
nock.get('/test')..responseDelay(Duration(seconds: 10))..reply(200, 'Ok');
Thanks
Hi there,
I've been eyeing your package with interest, and I wanted to point out something that I've been playing around with: https://github.com/shyndman/http-recorder
It's an http client that records all requests and responses, which includes multipart requests and streamed requests. It's built on top of the http package, and I've been chatting with the https://github.com/CodingAleCR/http_interceptor/ maintainer to see if I can get some of the ideas integrated.
Seems like it might be a good fit for nock too, as the JS lib has this ability.
Hello. Firstly, thanks for Nock, really makes mocking smooth.
I am curious if it is possible to set up Nock and run it when app is ran with a certain 'Mock' flavor?
The plan was to look somehow like this:
Future setupMock(String baseUrl) async {
final scope = nock(baseUrl);
scope.get('/portfolio').reply(200, getPortfolio);
scope.post('/portfolio').reply(201, getPortfolio);
scope.get('/payment-methods').reply(200, getPaymentMethods);
However, when I try running / debugging the app, I get the following error:
Error: Couldn't resolve the package 'nock' in 'package:nock/nock.dart'.
: Error: Not found: 'package:nock/nock.dart'
../โฆ/mock/setup_mock.dart:21
import 'package:nock/nock.dart';
^
Is it able to run Nock, or is it by design only intended for tests?
Hello, first of all apologies as this is not necessarily an issue but more of a question that I could not figure out from the docs or API reference. Is it possible to mock only certain URLs and not others?
For example, mock http://localhost:8080
urls, but do not mock URLs to https://flagcdn.com/
or some similar CDN?
Thanks
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.