I'm getting the following error when running Jest tests:
/Users/hugo/src/feedback/www/assets/app/node_modules/superagent/lib/node/index.js: /Users/hugo/src/feedback/www/assets/app/node_modules/superagent/node_modules/debug/node.js: Cannot read property 'buffer' of undefined
If Jest automatically mocks out dependencies, shouldn't any file that requires superagent just get the mock of superagent? All the functions I have that even make an http request using it have been mocked out to just return test data without making the request. I don't understand why I'm getting the error.
UPDATE
I tried the manual mock found here. It still gives me the same error.
Related
Hi I am new to unit testing and I am trying to mock the 'annotationManager' of the PDFtron webviewer
I am using this below code in my test file
jest.mock('#pdftron/webviewer', () =>({
annotationManager: {
getAnnotationsList: jest.fn().mockReturnValue([]),
deleteAnnotations: jest.fn()
},
}));
In the code, I'm getting the list of annotations using 'getAnnotationsList' function and deleting it using 'deleteAnnotations' function.
In the log of the unit tests, I'm getting this following error
'cannot read the properties of undefined (reading 'getAnnotationsList')
Is this the correct way to doing things or am I missing something?
are you able to share an example of a test you are writing where you need to mock the annotation manager? Depending on how you are using the WebViewer package, mocking the annotation manager can be different. If you prefer to reach out to Apryse directly you can also reach out to them via their support form
I have an application where I am trying to differentiate integration tests from unit tests. This difference is made through two types of files suffixes .ispec.ts for integration and .test.ts for unit.
Another difference between them is that unit tests shouldn't access the network, for that I've setup a mock for axios on <rootDir>/__mocks__/axios.ts which prevents that behavior successfully. For integration tests however, I'd like to go over the network and axios should keep it's normal operation.
To prevent axios from being mocked on ispec files, I am adding the following line in all the files:
// anyFile.ispec.ts
imports (...)
jest.unmock('axios'); // this line required in every .ispec file
describe(...)
Reading the jest documentation, I came across the following option unmockedModulePathPatterns where as the name suggests, defined modules on this array will be unmocked by the jest cli.
So I've changed my jest configurations for:
// jest.unit.js
module.exports = {
testRegex: '/__tests__/.+\\.test\\.ts$'
};
and
// jest.integration.js
module.exports = {
testRegex: '/__tests__/.+\\.ispec\\.ts$',
unmockedModulePathPatterns: ['axios']
}
To my surprise, after removing the line jest.unmock('axios') from my ispec files and running jest --config ./jest.integration.js still makes use of the mocked axios which is not my intention.
Did I miss the point of unmockedModulePathPatterns or is it a bug on jest configuration? I also tried setting automock to false, but the behavior is still the same.
I have been trying to configure offline unit tests for polymer web components that use the latest release of Firebase distributed database. Some of my tests are passing, but others—that look nigh identical to passing ones—are not running properly.
I have set up a project on github that demonstrates my configuration, and I'll provide some more commentary below.
Sample:
https://github.com/doctor-g/wct-firebase-demo
In that project, there are two suites of tests that work fine. The simplest is offline-test, which doesn't use web components at all. It simply shows that it's possible to use the firebase database's offline mode to run some unit tests. The heart of this trick is the in the suiteSetup method shown below—a trick I picked up from nfarina's work on firebase-server.
suiteSetup(function() {
app = firebase.initializeApp({
apiKey: 'fake',
authDomain: 'fake',
databaseURL: 'https://fakeserver.firebaseio.com',
storageBucket: 'fake'
});
db = app.database();
db.goOffline();
});
All the tests in offline-test pass.
The next suite is wct-firebase-demo-app_test.html, which test the eponymous web component. This suite contains a series of unit tests that are set up like offline-test and that pass. Following the idea of dependency injection, the wct-firebase-demo-app component has a database attribute into which is passed the firebase database reference, and this is used to make all the firebase calls. Here's an example from the suite:
test('offline set string from web component attribute', function(done) {
element.database = db;
element.database.ref('foo').set('bar');
element.database.ref('foo').once('value', function(snapshot) {
assert.equal(snapshot.val(), 'bar');
done();
});
});
I have some very simple methods in the component as well, in my attempt to triangulate toward the broken pieces I'll talk about in a moment. Suffice it to say that this test passes:
test('offline push string from web component function', function(done) {
element.database = db;
let resultRef = element.pushIt('foo', 'bar');
element.database.ref('foo').once('value', function(snapshot) {
assert.equal(snapshot.val()[resultRef.key], 'bar');
done();
});
});
and is backed by this implementation in wct-firebase-demo-app:
pushIt: function(at, value) {
return this.database.ref(at).push(value);
},
Once again, these all pass. Now we get to the real quandary. There's a suite of tests for another element, x-element, which has a method pushData:
pushData: function(at, data) {
this.database.ref(at).push(data);
}
The test for this method is the only test in its suite:
test('pushData has an effect', function(done) {
element.database = db;
element.pushData('foo', 'xyz');
db.ref('foo').once('value', function(snapshot) {
expect(snapshot.val()).not.to.be.empty;
done();
});
});
This test does not pass. While this test is running, the console comes up with an error message:
Your API key is invalid, please check you have copied it correctly.
By setting some breakpoints and walking through the execution, it seems to me that this error comes up after the call to once but before the callback is triggered. Note, again, this doesn't happen with the same test structure described above that's in wct-firebase-demo-app.
That's where I'm stuck. Why do offline-test and wct-firebase-demo-app_test suites work fine, but I get this API key error in x-element_test? The only other clue I have is that if I copy in a valid API key into my initializeApp configuration, then I get a test timeout instead.
UPDATE:
Here is a (patched-together) image of my console log when running the tests.:
To illustrate the issue brought up by tony19 below, here's the console log with just pushData has an effect in x-element_test commented out:
The offline-test results are apparently false positives. If you check the Chrome console, offline-test actually throws the same error:
The error doesn't affect the test results most likely because the API key validation occurs asynchronously after the test has already completed. If you could somehow hook into that validation, you'd be able to to catch the error in your tests.
Commenting out all tests except for offline firebase is ok shows the error still occurring, which points to suiteSetup(). Narrowing the problem down further by commenting 2 of the 3 function calls in the setup, we'll see the error is caused by the call to firebase.initializeApp() (and not necessarily related to once() as you had suspected).
One workaround to consider is wrapping the Firebase library in a class/interface, and mocking that for unit tests.
I have 2 tests which are testing a view that makes a call to an external module. I've mocked it with mock.patch. I'm calling the view by using django's test client.
The first test (a test for 404 being returned) completes successfully and the correct mock is called.
When the second test runs, everything runs as normal, but the mock that the code-under-test has access to is the mock from the previous test.
You can see in this example https://dpaste.de/7zT8 that the ids in the test output are incorrect (around line 91).
Where is this getting cached? My initial thought was that the import of the main module is somehow cached between test runs due to urlconf stuff. Tracing through the source code, I couldn't find that as the case.
Expected: Both tests pass.
Actual: Second test fails due to stale mocked import.
If I comment out the 404 test, the other test passes.
The view is registered in the url conf as the string-y version 'repos.views.github_webhook'.
I do not fully understand what causes the exact behaviour you are seeing, especially not why the mock is seemingly working correctly in the first test. But according to the mock docs, you should patch in the namespace under test, i.e. patch("views.tasks").
http://www.voidspace.org.uk/python/mock/patch.html#where-to-patch
Is there a way to inject providers when writing unit tests using Karma(Testacular) and Jasmine in angular?
Our team decided recently to use angularjs $log to write debugging details to the console. This way we can leverage the ability to disable the logging via the $logProvider.debugEnabled() method.
angular.module("App", ["prismLogin", "ui.bootstrap"])
.config(["$routeProvider", "$logProvider",
function ($routeProvider, $logProvider) {
$routeProvider
//routes here edited for brevity
//This is the offending line, it breaks several pre-existing tests
$logProvider.debugEnabled(true);
}]);
However after adding the $logProvider.debugEnabled(true); line several of our tests no longer execute successfully, failing with the following message:
TypeError: Object doesn't support property or method 'debugEnabled' from App
So my question again, is it possible to mock the $logProvider? Or should I provide my own configuration block for the test harness?
I attempted searching for a way to mock the app module with no luck. It seems to me that using the concrete app module instead of a mock is very brittle. I would like to avoid reworking tests associated with the app module every time a change is made in the app or run configuration blocks.
The tests that are failing are units of code with no relation to the $logProvider? I feel as if I a missing something here and making things much harder than they should be. How should one go about writing tests that are flexible and are not affected by other side effects introduced in your application?
It appears that this is a know issue with angular-mocks.
Until the issue is addressed , I was able to resolve the issue by adding the following method to the angular.mock.$LogProvider definition in angular-mocks.js at line 295.
this.debugEnabled = function(flag) {
return this;
};