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!
Related
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
The following code throws error as : TypeError: Cannot read property 'trim' of undefined
this.setState({
details: {
...this.state.details,
[classificationType]: [value.trim()]
}
});
How to improve jest test cases to consider string features?
Might be you are not getting value that's why it is unable to read trim() function on that. Can you please explain from where you are getting value? What mock data you used to execute your test case?
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.
I am trying to test a fairly simple JavaScript function in Jasmine, however the first statement is throwing an error for being undefined.
myClass.prototype.functiontoBeTested = function() {
var x = this.method()
...
}
The above throws an error in Jasmine as method is not a function and is undefined. The prototype is altered earlier to have this method, and out of curiosity I assigned this method to my test object in the spec itself as such:
myObject.method = function(){return mockResults;};
So I decided to log this to the console and instead of it being my object, I see Window {top: Window, location: Location, document: document, window: Window, external: Object…} which doesn't seem right. I've had this issue before with testing a function in Jasmine that used this but just changed the source code to refer to the object by name since the function was being assigned to something within the closure. I can't do that in this case, and I'm curious why this is referring to something unexpected (at least to me).
Edit: Some details on what the test case looks like as requested:
it("updates the control count", function(){
var mockResults = { ... };
myObject.method = function() {return mockResults;};
expect(myObject.method).not.toThrow();
});
Right now I'm just trying to get the method to execute to completion during the test. The function to be tested updates the text on some HTML components, I'll work on verifying those once I can get it to actually run. The method that is causing an error is the first line of the function, and is simply an accessor method for the object being called. In actual execution, var x = this.method() runs without issue. When testing in jasmine var x = this.method() throws an error because method() is undefined for this. Instead of this referring to the calling object, it is referring to the window. This doesn't happen live, but only during testing with Jasmine. This method is undefined even when I forcibly define it for the test object just prior to execution in the test as above. That's when I decided to log this to console in the source code and realized it isn't referring to what I would have expected it to refer to.
In JavaScript this for a method depends on the context it was called from. When you do a call myObject.method(), then method was called from the context of myObject, therefore this is myObject.
When you pass your function to Jasmine toThrow matcher, it calls it as it was passed (see source code):
try {
actual();
} catch (e) {
// ....
}
Here, actual() is a call of your method. It has no any specific context, so by default it will be called from window context.
Solution is to explicitly bind you method to myObject like the following:
expect(myObject.method.bind(myObject)).not.toThrow();
Credits to questions, you can find more details there:
Does Jasmine's toThrow matcher require the argument to be wrapped in an anonymous function?
How to write a test which expects an Error to be thrown in Jasmine?
When I run my jasmine specs I get the following error:
Error: Expected a spy, but got undefined.
My coffeescript code:
describe "setupForm", ->
beforeEach ->
spyOn(Subscription.prototype, 'runSimulation')
it "calls subscription.runSimulation when form is submitted with number", ->
Subscription.prototype.runSimulation()
expect(Subscription.prototype.runSimulation()).toHaveBeenCalled()
I have simplfied my erroring code to the above for debugging, but I can't figure out why it is saying the spy is never called when I'm explicitly calling it my test. I am testing the method in other places, so I think the error has to be with how I am using the Jasmine Spy. Thanks.
Take the () off the end of Subscription.prototype.runSimulation():
expect(Subscription.prototype.runSimulation).toHaveBeenCalled()