MockClient 1 positional argument(s) expected, but 0 found - flutter

I'm trying to create some tests for flutter app with Mockito.
This is my code:
#GenerateMocks([http.Client])
main() {
group('sendUrlPost', () {
test('returns alias and links if the post call is successful', () async {
final client = MockClient();
String apiUrl = "someApiURL";
String longUrl = "someUrl";
when(client.post(Uri.parse(apiUrl),
headers: {'Content-Type': 'application/json'},
body: jsonEncode(
{"url": longUrl}))).thenAnswer((_) async => http.Response(
'{"alias":"70492","_links":{"self":"https://www.youtube.com","short":"https://url-shortener-nu.herokuapp.com/short/70492"}}',
200));
expect(await UrlPostConnector.sendUrlPost(longUrl), isA<UrlResponse>());
});
});
}
I have followed exactly what the official guide has:
https://docs.flutter.dev/cookbook/testing/unit/mocking
but when I create the mock client I get the following error:
final client = MockClient();
1 positional argument(s) expected, but 0 found. Try adding the
missing arguments
I'm guessing the guide is outdated but I haven't found a way to make it work. I would apprecieate if you can tellme what I'm doing wrong and if there is a better way to test an Http request.
Thanks

I was missing the generated mocks.dart file that is created by running
flutter pub run build_runner build
Thanks to #jamesdlin for pointing that out.

You have to lower down the version to 5.0.0
mockito: ^5.0.0
Make sure you run this command after creating test class
flutter pub run build_runner build

Related

how to run command in Dart correctly?

That's my code. I want to use Process.run to open a command to do something, like git clone or flutter build.
import 'dart:io';
void main() async {
print('build start');
// var res = await Process.run('git clone xxxx', []);
var res = await Process.run('flutter build windows --dart-define=RunEnv=dist', []);
print(res);
print('build end');
}
But it failed.
Unhandled exception:
ProcessException: 系统找不到指定的文件。
Command: flutter
Dart Process can't read global command variable like flutter or git? In nodejs is easy to do that. What should I do?
Your syntaxis is not right. All parameters have to supplied as a list of string, rewrite it to:
final ProcessResult res = await Process.run(
'flutter',
<String>[
'build',
'windows',
'--dart-define=RunEnv=dist'
],
);
[Edit] Link to documentation: https://api.flutter.dev/flutter/dart-io/Process/run.html [/edit]

I get Error: Type 'Dio' not found when using Retrofit and Dio together

I just added retrofit to my Flutter app and generated a class as explained here.
But when I want to run my app I get the following error:
Running Gradle task 'assembleAppdevDebug'...
lib/folder/service.g.dart:14:9: Error: Type 'Dio' not found.
I use the following dependencies
dependencies:
dio: ^4.0.6
retrofit: 3.0.1
dev_dependencies:
json_serializable: ^6.2.0
analyzer: ^2.8.0
build_verify: ^3.0.0
retrofit_generator: 3.0.1
build_runner: ^2.1.2
The class definition looks like this
#RestApi(baseUrl: 'https://someapi.com/')
abstract classService {
factory Service(dio.Dio dio, {String baseUrl}) = _Service;
#Headers({
'contentType': 'application/json',
})
#POST('path')
Future<User> createUser(
#Body() User user,
);
}
I found out what the problem was. When I defined the abstract class and added the #Headers annotation the IDE complained that both DIO and Retrofit contained a headers annotation and that I therefore should specify an alias import:
Which I then did by specifying import 'package:dio/dio.dart' as dio;
The alias import though was the reason why the generated _Service file couldn't find Dio.
Solution:
Import retrofit as import 'package:retrofit/retrofit.dart' as rf;
Define the headers as rf.Headers()
#rf.Headers({
'contentType': 'application/json',
})
#POST('path')
Future<User> createUser(
#Body() User user,
);

Dart/Flutter Web unit testing errors: Error: Not found: 'dart:html'

I'm working on a Flutter web app and I'm having trouble running a test.
Flutter 1.7.8+hotfix.4 • channel stable • git#github.com:flutter/flutter.git
Framework • revision 20e59316b8 (9 weeks ago) • 2019-07-18 20:04:33 -0700
Engine • revision fee001c93f
Tools • Dart 2.4.0
This is the pubspec.yaml:
name: web_flutter
description: An app built using Flutter for web
environment:
# You must be using Flutter >=1.5.0 or Dart >=2.3.0
sdk: '>=2.3.0-dev.0.1 <3.0.0'
dependencies:
flutter_web: any
flutter_web_ui: any
provider: any
rxdart: ^0.22.0
http: ^0.12.0+2
json_annotation: ^2.4.0
intl: 0.15.8
dev_dependencies:
build_runner: ^1.4.0
build_web_compilers: ^2.0.0
pedantic: ^1.0.0
json_serializable: ^3.0.0
test: any
flutter:
uses-material-design: true
dependency_overrides:
flutter_web:
git:
url: https://github.com/flutter/flutter_web
path: packages/flutter_web
flutter_web_ui:
git:
url: https://github.com/flutter/flutter_web
path: packages/flutter_web_ui
provider:
git:
url: https://github.com/kevmoo/provider
ref: flutter_web
I wrote a couple of tests that are passing when I run pub run test in either the IDE's terminal (VS Code) or in terminal app.
The test I'm having trouble with requires some package imports from the project. With this test in place I get errors and the other two tests don't run. I haven't found anything that points to a solution.
This is the error message:
pub run test MyMac#MyMac
00:06 +0 -1: loading test/service_test.dart [E]
Failed to load "test/service_test.dart":
Unable to spawn isolate: file:///Users/MyMac/.pub-cache/git/flutter_web-c04fb502b842859de07e36954a9390465a5426c0/packages/flutter_web_ui/lib/ui.dart:12:8: Error: Not found: 'dart:html'
import 'dart:html' as html;
^
file:///Users/MyMac/.pub-cache/git/flutter_web-c04fb502b842859de07e36954a9390465a5426c0/packages/flutter_web_ui/lib/src/engine.dart:11:8: Error: Not found: 'dart:html'
import 'dart:html' as html;
^
file:///Users/MyMac/.pub-cache/git/flutter_web-c04fb502b842859de07e36954a9390465a5426c0/packages/flutter_web/lib/src/services/asset_bundle.dart:7:8: Error: Not found: 'dart:html'
import 'dart:html' show HttpRequest;
^
file:///Users/MyMac/.pub-cache/git/flutter_web-c04fb502b842859de07e36954a9390465a5426c0/packages/flutter_web_ui/lib/src/engine.dart:12:8: Error: Not found: 'dart:js'
import 'dart:js' as js;
^
file:///Users/MyMac/.pub-cache/git/flutter_web-c04fb502b842859de07e36954a9390465a5426c0/packages/flutter_web_ui/lib/src/engine.dart:13:8: Error: Not found: 'dart:js_util'
import 'dart:js_util' as js_util;
^
file:///Users/MyMac/.pub-cache/git/flutter_web-c04fb502b842859de07e36954a9390465a5426c0/packages/flutter_web_ui/lib/src/ui/compositing.dart:20:9: Error: Type 'html.Element' not found.
final html.Element webOnlyRootElement;
^^^^^^^^^^^^
file:///Users/MyMac/.pub-cache/git/flutter_web-c04fb502b842859de07e36954a9390465a5426c0/packages/flutter_web_ui/lib/src/engine.dart:177:37: Error: Type 'html.NodeTreeSanitizer' not found.
class _NullTreeSanitizer implements html.NodeTreeSanitizer {
^^^^^^^^^^^^^^^^^^^^^^
file:///Users/MyMac/.pub-cache/git/flutter_web-c04fb502b842859de07e36954a9390465a5426c0/packages/flutter_web_ui/lib/src/engine.dart:179:21: Error: Type 'html.Node' not found.
void sanitizeTree(html.Node node) {}
^^^^^^^^^
file:///Users/MyMac/.pub-cache/git/flutter_web-c04fb502b842859de07e36954a9390465a5426c0/packages/flutter_web_ui/lib/src/engine/bitmap_canvas.dart:26:9: Error: Type 'html.Element' not found.
final html.Element rootElement = html.Element.tag('flt-canvas');
^^^^^^^^^^^^
file:///Users/MyMac/.pub-cache/git/flutter_web-c04fb502b842859de07e36954a9390465a5426c0/packages/flutter_web_ui/lib/src/engine/bitmap_canvas.dart:28:3: Error: Type 'html.CanvasElement' not found.
html.CanvasElement _canvas;
^^^^^^^^^^^^^^^^^^
00:06 +0 -1: Some tests failed.
If I comment out this new test, the errors persist. If I comment out the test and the related imports the remaining two tests run and pass.
This is the test file (I left the offending code commented out so it's easier for you to see - I hope).
import 'package:test/test.dart';
import 'package:http/http.dart';
import 'package:http/testing.dart';
import 'dart:convert';
import 'package:web_flutter/services/service.dart';
// These are the package imports that cause errors:
import 'package:web_flutter/model/model.dart';
import 'package:web_flutter/data/tenant_view_model.dart';
void main(){
test("getSubmission returns ResponseData{}", () async {
// Arrange: setup the test
final _service = Service();
_service.httpClient = MockClient((request) async {
final responseData = {
"id": "some_id",
"state": "processed",
"test": true,
"editable": false,
"expires_at": "2019-09-19T03:40:22Z",
"processed_at": "2019-09-12T03:40:22Z",
"batch_id": "",
"download_url": "downloadURl.com",
"permanent_download_url": "permanentdownloadURL.com"
};
return Response(json.encode(responseData),200);
});
// Act
final response = await _service.getSubmission("submissionID");
// Assert
expect(response.download_url, "downloadURL.com");
});
test("generateForm returns SubmissionResponse{}", () async {
// Arrange: setup the test
final _service = Service();
_service.httpClient = MockClient((request) async {
final submissionResponse = {
"status": "success",
"submission": {
"id": "some_id",
"state": "pending",
"test": false,
"editable": false,
"expired": false,
"expires_at": null,
"metadata": {
"foo": 123,
"bar": "baz"
},
"processed_at": null,
"batch_id": null,
"data_requests": [],
"download_url": null,
"permanent_download_url": null
}
};
return Response(json.encode(submissionResponse),200);
});
// Act
final response = await _service.generateForm(42, "templateID");
// Assert
expect(response.submission.id, "some_id");
});
test('Tenant View Model generateForm returns tenantVM.submission.submission.id', () async {
// Arrange
final _service = Service();
Tenant tenant;
tenant.id = 42;
_service.httpClient = MockClient((request) async {
final submissionResponse = {
"status": "success",
"submission": {
"id": "some_id",
"state": "pending",
"test": false,
"editable": false,
"expired": false,
"expires_at": null,
"metadata": {
"foo": 123,
"bar": "baz"
},
"processed_at": null,
"batch_id": null,
"data_requests": [],
"download_url": null,
"permanent_download_url": null
}
};
return Response(json.encode(submissionResponse),200);
});
TenantViewModel tenantVM = TenantViewModel(tenant, _service);
// Act
await tenantVM.generateForm("templateID");
// Assert
expect(tenantVM.submission.submission.id, "some_id");
});
}
This is the class that has the method I'm trying to test (generateForm()).
import 'package:flutter_web/cupertino.dart';
import 'package:web_flutter/model/model.dart';
import 'package:web_flutter/services/service.dart';
class TenantViewModel with ChangeNotifier {
Tenant _tenant;
Property _property;
Service _service;
SubmissionResponse _submission;
ResponseData _responseData;
TenantViewModel(this._tenant, this._service);
bool get isNew => _tenant.id == null;
set tenant(Tenant tenant) {
if (_tenant != tenant) {
_tenant = tenant;
notifyListeners();
}
}
Tenant get tenant => _tenant;
set property(Property property) {
_tenant.propertyId = property.id;
notifyListeners();
}
Property get property => _property;
set submission(SubmissionResponse submission) {
if (_submission != submission) {
_submission = submission;
notifyListeners();
}
}
SubmissionResponse get submission => _submission;
set responseData(ResponseData responseData) {
if (_responseData != responseData) {
_responseData = responseData;
notifyListeners();
}
}
ResponseData get responseData => _responseData;
Future generateForm(String templateID) async {
SubmissionResponse submission;
submission = await _service.generateForm(_tenant.id, templateID);
this.submission = submission;
notifyListeners();
}
Future getSubmission(String submissionID) async {
ResponseData responseData;
responseData = await _service.getSubmission(submissionID);
this.responseData = responseData;
notifyListeners();
}
Future save() async {
Tenant updatedTenant;
if (tenant.isNew) {
updatedTenant = await _service.createTenant(_tenant);
this.tenant = updatedTenant;
} else {
updatedTenant = await _service.updateTenant(tenant);
this.tenant = updatedTenant;
}
notifyListeners();
}
Future refresh() async {
if (isNew) {
return;
}
var updatedTenant = await _service.getTenant(_tenant.id);
if (_tenant.propertyId != null) {
_property = await _service.getProperty(_tenant.propertyId);
}
_tenant = updatedTenant;
notifyListeners();
}
}
I have tried:
import 'package:flutter_test/flutter_test.dart'; in the test file and adding this to the pubspec.yaml:
flutter_test:
sdk: flutter
These cause their own varieties of errors, because I'm using Flutter Web, not Flutter. Can anyone see where I'm going wrong?
I am aware that the test I'm working on is probably wrong as it is, but I can't even get to the point of having it run and fail.
I had a similar issue while developing for a mobile app, but it turned out that I imported the package dart.html accidentally. I just removed it and I was able to run the program.
Since you are running flutter tests for web that use the dart:html package you must target the correct platform.
flutter test --platform chrome
It can happen when you try to import something like #required. Then flutter will accidentally put import dart.html above the code. Just remove that from the code and then you will fix your issue.
Change import 'dart:html'; to import 'package:http/http.dart' as http;
and then change pubspec.yaml files dependencies to
dependencies:
flutter:
sdk: flutter
http:
and click pub get
In which file you had added import 'dart:html' just remove this and then execute the code again. I think the problem will be solved. Following this i had solved my problem.
The problem comes because, as my tech lead pointed out, "Unit tests do not have access to dart:html. Unless you run them in the browser."
From pub.dev/packages/test:
"By default, tests are run in the Dart VM [virtual machine], but you can run them in the browser as well by passing pub run test -p chrome path/to/test.dart. test will take care of starting the browser and loading the tests, and all the results will be reported on the command line just like for VM tests. In fact, you can even run tests on both platforms with a single command: pub run test -p "chrome,vm" path/to/test.dart"
To solve my particular problem I ran the tests using pub run test test/print_reports_card_test.dart -p chrome.
Another solution in case you have tests for both web and mobile is to add #TestOn('browser') at the top of your test file.
Here's the full doc
This error sometimes occurs when the language mode is out of place. Ensure that the "select language mode" (The yellow circle in the image) is on the right mode. For this instance it should be Dart
removing import 'dart:html';
from the file worked for me also changing platform to chrome works
You need to do some conditional import and implement the components you accessed in "dart:html" to your own file
Here's an example in a case where I am making use of dart:html's window.open
window_service.dart
Window window = Window();
class Window {
void open(String url, String name, [String? options]) {}
}
with the above you can do:
import "window_service.dart" if (kIsWeb) "dart:html" as html;
...
html.window.open(url, name, options);
Do the same for every dart:html calls you made by implementing them with similar/same structure in the dummy file (window_service.dart). Then you may now run your tests without error.

Does testcafe support testing of rest api

Tests hang in the testcafe browser when you try to test a rest api url directly.
I am trying to run a test against my rest API endpoint using request hooks, but when I run the test from the command line, the browser opens the API endpoint and loads it and hangs. The test doesn't pass or fail and hangs. The rest API endpoint just returns a JSON response.
const logger = RequestLogger('https://example.com/search/suggestions?search=testkeyword');
fixture `test`
.page('https://example.com/search/suggestions?search=testkeyword');
test
.requestHooks(logger)
('test', async t => {
// Ensure that the response has been received and that its status code is 200.
await t.expect(logger.contains(record => record.response.statusCode === 200)).ok();
const logRecord = logger.requests[0];
console.log(logRecord.userAgent);
console.log(logRecord.request.url);
console.log(logRecord.request.method);
console.log(logRecord.response.statusCode);
});
I expect the test to pass checking for 200 status code, but the test hangs without showing pass/fail. Does testcafe support testing of rest API endpoints? I have checked this issue - https://github.com/DevExpress/testcafe/issues/1471 where it says testcafe doesn't support non-html pages. Please confirm.
You are right, TestCafe is intended to work with html pages, but it will use the "about:blank" page if you don't define any url. You can use the regular node.js HTTP API without request hooks for this case. Look at the following example:
import http from 'http';
const getResponseData = (url) => new Promise((resolve, reject) => {
http.get(url, res => {
const { statusCode } = res;
const contentType = res.headers['content-type'];
res.setEncoding('utf8');
let rawData = '';
res.on('data', (chunk) => { rawData += chunk; });
res.on('end', () => resolve({ statusCode, contentType, rawData }));
}).on('error', e => reject(e));
});
fixture `Test REST API`;
test('Simple Test', async t => {
const response = await getResponseData('http://example.com/api/1');
await t
.expect(response.statusCode).eql(200);
});
TestCafe 1.20.0+ offers the t.request method. You can use it for REST API testing. In other words, you can incorporate API testing right into your existing functional TestCafe tests. You no longer need to use any third-party libraries.
You can read about the API testing feature in the corresponding guide.

Failed to get token

Trying to fetch some data into the cloud firestore database and when I do this I get this error Failed to get token: com.google.firebase.firestore.FirebaseFirestoreException: getToken aborted due to token change..
pubspec.yaml
cloud_firestore: ^0.9.7
firebase_auth: ^0.8.1+4
android/build.gradle:
dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
classpath 'com.google.gms:google-services:3.1.0'
}
Method that fetched the employee_information:
static addEmployee(Map<String, dynamic> snapshot){
Firestore.instance.runTransaction((Transaction tx) async{
await tx.set(Firestore.instance.collection('employee').document(),snapshot);
});
}
If you've come across this issue let me know, thanks!
for ERROR [FirestoreCallCredentials]: Failed to get token:
go to https://console.cloud.google.com/ - select your project
Select API&Services
Select Credentials
and Update the values in API Keys