SinonJS Spy Cannot Restore Read Only Method/Property of Object - javascript

It gives me TypeError: Cannot assign to read only property 'get' of object '#<Config>'.
I'm using mocha 8.0.1, chai 4.2.0, sinon 9.0.2 for Unit Testing.
I'm spying on a method in the config npm package.
Here's how I spy the get method:
...
before(() => {
sandbox = sinon.createSandbox();
configStub = sandbox.spy(config, 'get');
});
after(() => {
sandbox.restore();
});
it('should something', async () => {
console.log('Just logging');
config.get('LOG.LEVEL'); // just to show the point. if I remove this line, it doesn't throw the error
});
...
What happens is, if I run config's get method somewhere during the test, it can not be restored by spy. It throws that read-only property error. But when the config.get function is never called, it doesn't throw that error (I don't understand why not). For stub there's no problem, it can restore just fine.
But the reason I'm using spy is because I want config.get to work like it normally does while I'm testing my module/function that's using it, I just want to spy on it. And I also need to be able to restore it after this test suite. I spy on it because I need to test that it's being called by my module/function with some specific parameters.
How do I spy on a read-only property/method, allow my module/function to use it like it normally does, and then restore it?
Thank you :)

You can set ALLOW_CONFIG_MUTATIONS environment variable to true for the test run.
In this way config.get invocation will not freeze the config which should resolve the issue.
You can find the env var description in the documentation:
https://github.com/lorenwest/node-config/wiki/Environment-Variables#allow_config_mutations

Related

The following error originated from your application code, not from Cypress

i tried to test this simple code
type Url = string
it('loads examples', () => {
const url: Url = 'https://www.ebay.com/'
cy.visit(url)
cy.get('input[type="text"]').type('book')
cy.get('#gh-btn').click();
})
then I faced this error
how can I solve it
Try adding this in support/index.js:
import './commands'
Cypress.on('uncaught:exception', (err, runnable) => {
// returning false here prevents Cypress from failing the test
return false
})
This should avoid the uncaught:exception in the click() method.
The accepted answer will cause Cypress to ignore all uncaught exceptions in the application. Generally, when these come up it means you found a bug in your app and should fix it.
Binding to the global Cypress object causes the event to stay bound for your entire test run. Usually, this isn't what you want.
If you actually need to ignore the exceptions though, you should be binding the event on the cy object so it's only persisted for the single test it's used in.
it('my test', () => {
cy.once('uncaught:exception', () => false);
// action that causes exception
cy.get('body').click();
});
I got Same Issue like this
Cypress Error
The following error originated from your application code,
not from Cypress. >
Cannot read properties of null (reading 'textContent')
When Cypress detects uncaught errors originating from
your application it will automatically fail the current test.
This behavior is configurable, and you can choose to turn this off by
listening to the uncaught:exception event.Learn more
No Need to worry about this.
Just paste this code to your index.js file :)
import './commands'
Cypress.on('uncaught:exception', (err, runnable) => {
// returning false here prevents Cypress from
// failing the test
return false
})
Actually, if you click in the Learn more link that comes with the error, you'll get everything you need.
https://docs.cypress.io/guides/references/error-messages#Uncaught-exceptions-from-your-application
Quoting others:
won't this answer ignore all errors thrown by the application?
The accepted answer will cause Cypress to ignore all uncaught exceptions
That is true.
Also, #DJSDev did not work for me when using Cypress v10.0.3.
The aforementioned link provides a working alternative:
it('is doing something very important', (done) => {
// this event will automatically be unbound when this
// test ends because it's attached to 'cy'
cy.on('uncaught:exception', (err, runnable) => {
expect(err.message).to.include('something about the error')
// using mocha's async done callback to finish
// this test so we prove that an uncaught exception
// was thrown
done()
// return false to prevent the error from
// failing this test
return false
})
// assume this causes an error
cy.get('button').click()
})

Window object not defined in jasmine

I am trying to test a method where one of the thing that it does it lock orientation of screen. Jasmine however is throwing error in the line:
(<any>window).screen.orientation.lock('portrait') saying that undefined is not a constructer.
I even tried not using typescript types and just window.screen.msOrientationLock('landscape') and other window.screen methods but I get same error. I have the _$window_ injected in beforeEach of my tests too.
Testing if it locks is not necessary part of my test so is there some way to skip this specific line or correct this error. Thanks :)
Well it was easy. I had to inject window object and assign it to a global variable in my global beforeEach like this:
$window = _$window_;
Then, the next issue was that the property orientation was not available in the window.screen object unfortunately. I just had to mock it inside my spec like this:
$window.screen.orientation = {
lock: function() { return; }
};
Just had to do this before spying/calling the method which had window.screen.orientation.lock method inside it.

Cannot spy on angular.element

I have one Jasmine test that is continously failing due to a spyOn not executing.
The following test will automatically fail:
it('simple test', function() {
spyOn(angular, 'element');
});
The error is:
TypeError: 'undefined' is not an object (evaluating 'angular.element(handle.elem).off')
at /Users/geoff/Project/www/components/angular-mocks/angular-mocks.js:1946
at /Users/geoff/Project/www/components/angular-mocks/angular-mocks.js:1977
This error only seems to happen with angular.element. spying on other angular methods such as angular.copy and angular.forEach do not throw this error. I am using Jasmine 2.0 and Angular ~1.3. Any advice on fixing this problem would be appreciated.
You need to allow access to the real object.
spyOn(angular, 'element').and.callThrough();
The code is trying to access a property on the return value, but the spy is not returning anything. You can't access .off on an undefined object!

How to intercept error when expect fails? Jasmine and frisby

I am creating HTTP tests with frisby.js which works on top of jasmine.js.
I also have to create some mongoDB objects to test against.
The problem is when I want to clean up these DB objects. When one of the expects fail I want to intercept that and call my own cleanup function. This means that after each failed test, I won't be able to remove the test objects from the DB.
The afterEach function in jasmine does not work properly and jasmine does not have any support for afterAll or beforeAll yet.
That is why I have made the tests as they are today.
it("testing userform get with correct userID and expect correct return", function() {
var innerUserId = userID;
frisby.create('Should retrieve correct userform and return 200 when using a valid userID')
.get(url.urlify('/api/userform', {id: innerUserId}))
.expectStatus(200)
.afterJSON(function(userform){
// If any of these fail, the after function wont run.
// I want to intercept the error so that I can make sure that the cleanUp function is called
// afterEach does not work. I have tried with done()
var useridJSON = userform.UserId.valueOf();
var firstnameJSON = userform.firstname.valueOf();
var surnameJSON = userform.surname.valueOf();
expect(firstnameJSON).toMatch(testUser.firstName);
expect(surnameJSON).toMatch(testUser.surname);
expect(useridJSON).toMatch(innerUserId);
})
.after(function(){
cleanUp(innerUserId);
})
.toss();
});
I am wondering if there is a way to intercept the error for "expect" in frisby or jasmine so that I can make a call to my own cleanup function before exiting.
Full example here
The quickest solution to this problem is to wrap the error code in a try-catch.
This is because if a javascript error occurs, jasmine will NOT keep running assertions. This is different from an assertion error. If an assertion error occurs, jasmine and frisby will keep on testing all the other assertions and then do the "after"-function.
.afterJSON(function(userform){
try {
var useridJSON = userform.UserId.valueOf();
var firstnameJSON = userform.firstname.valueOf();
var surnameJSON = userform.surname.valueOf();
catch(e) {
cleanUp(innerUserId);
// Can do a throw(e.message); here aswell
}
expect(firstnameJSON).toMatch(testUser.firstName);
expect(surnameJSON).toMatch(testUser.surname);
expect(useridJSON).toMatch(innerUserId);
})
This is not the pretty way, but works.
I ended up adding the throw(e) and placed the expects in a finally scope. This way I got jasmine to present all the errors that occured in the test.
As for "before exiting", how about this:
process.on('uncaughtException', function(err) {
console.error(' Caught exception: ' + err);
});

How to test Jasmine setup code?

Update: I figured out what the issue was, see my comment below.
Is there a way to guarantee state before each Jasmine test?
For example:
describe('some thing', function () {
beforeEach(function () {
doSetup();
// this expect does not evaluate :(
expect(something).toBe(inSomeState);
});
it('has some behavior', function () {
// test code
});
});
The expect inside of the setup make no difference at all. Even throwing an error in the beforeEach does nothing. I would like to have some assurance that the setup has completed correctly before running the next test.. is there a way to do this?
Okay I see what the issue is. Hoping this will help other people out there having this same issue. grunt-contrib-jasmine does not display errors or failed expects inside of beforeEach or afterEach with the display option set to short. Setting this option to full will once again display Errors and failed expects.

Categories

Resources