Consider this:
function () {
var toast = new Toaster.ToastMessage({
title: Resources.Localised.COPY_Success,
message: Resources.Localised.COPY_CaseSavedSuccess,
severity: Toaster.ToastSeverity.Success,
position: Toaster.ToastPosition.TopRight
});
toast.show();
}
In jasmine, is there a way to verify show() is called? I'm thinking not, actually it makes sense that it wouldn't.
I have no access to the variable toast.
spyOn(Toaster.ToastMessage, "show"); does not work.
I've played with createSpyObj (jasmine.createSpyObj('Toaster.ToastMessage', ['show']);) without success.
Thanks.
You could try to spy on the prototype of Toaster.ToastMessage:
spyOn(Toaster.ToastMessage.prototype, "show")
You could use
spyOn(Toaster.ToastMessage, "show");
and then after the "show" method is executed use:
expect(Toaster.ToastMessage.show).toHaveBeenCalledTimes(1);
Related
I need to check for fullscreen support with my Go WASM Canvas project, before switching to fullscreen mode. I have the following code so far:
var fullscreenFunc js.Value
var fullscreenNotSupported bool
set with the following logic:
fullscreenFunc = app.Get("requestFullscreen")
if fullscreenFunc.IsUndefined() {
fullscreenFunc = app.Get("mozRequestFullScreen")
if fullscreenFunc.IsUndefined() {
fullscreenFunc = app.Get("webkitRequestFullscreen")
if fullscreenFunc.IsUndefined() {
fullscreenFunc = app.Get("msRequestFullscreen")
if fullscreenFunc.IsUndefined() {
fullscreenNotSupported = true
println("Fullscreen not supported")
}
}
}
}
I was expecting to be able to call the correct function with js.Invoke, but I see no way to tell the Invoke upon which object the call should be made. My 'app' value is being interpreted just as a param.
func Fullscreen(app js.Value) {
if fullscreenNotSupported {
return
}
fullscreenFunc.Invoke(app)
}
resulting in:
panic: JavaScript error: 'mozRequestFullScreen' called on an object that does not implement interface Element.
So am I correct in my thinking that the only way I can call the correct method, is not to store the Function, but to store a string of the function name, and then 'invoke' / 'call' it using the following approach?
app.Call(fullscreenFunctionNameString)
It feels like I misunderstood the purpose of Invoke. Is it only for js.Global() type calls?
[edit] Using 'Call', at least it seems possible to derive the function name without having to repeat the above browser specifics:
fullscreenFunctionName = fullscreenFunc.Get("name").String()
app.Call(fullscreenFunctionNameString)
It doesn't answer the question, but is probably of help to someone trying to do the same.
The arguments to invoke get turned into arguments for the javascript function it wraps. Since those fullscreen functions don't need any arguments, I think you might just need to change:
fullscreenFunc.Invoke(app)
To:
fullscreenFunc.Invoke()
...assuming app is the same JS element in both places. If not your Call solution is probably your best bet.
I have a function in my service as:
logError(message: string, stack: string) {
console.log('LoggingService: ' + message);
}
and I want to test this function test case I am writing are as:
it('should be created', inject([LoggerService], (loggerService: LoggerService) => {
expect(loggerService).toBeTruthy();
}));
it('log error should be called', inject([LoggerService], (loggerService: LoggerService) => {
spyOn(loggerService, 'logError');
expect(loggerService.logError).toHaveBeenCalled();
expect(loggerService.logError).toHaveBeenCalledTimes(1);
}));
Problem is when I run tests and I see code coverage it shows that logError function is not covered and also the console.log statement is not covered.
But when I change my approach from spyOn to call the actual method it says there are no expectations and I am not sure what will be the right expectaion in this case?
Any help on recommended approach is appreciated.
spyOn installs a spy onto a method of an existing object but it doesn't invoke that method. Therefore, after installing the spy on a method, you need to call the method under test, which is supposed to invoke the spied/mocked method.
it('log error should be called', inject([LoggerService], (loggerService: LoggerService) => {
spyOn(console, 'log');
const error = 'abc';
loggerService.logError(...);
expect(console.log).toHaveBeenCalledTimes(1);
expect(console.log)toHaveBeenCalledWith(error);
}));
I want to know how the "spyOn" function works internally. I read that the 'spyOn' function internally replaces the implementation of the function being spied on. Does it keep the old functionality?
As an example, suppose I wanted to spy on an object that sends data to a server.
describe("A spy", function() {
var object;
spyOn(object, 'sendDataToServer');
object.sendDataToServer('Some Message');
});
In this case, does the message still get sent to the server or does the spy mock it?
The message does not get sent to the server. The way you defined the spy, it will replace the sendDataToServer function whenever it is called in the context of your test case.
You can specify a more elaborate spy, for example when you want to call another function instead:
let mySpy = spyOn(object, 'sendDataToServer').and.callFake((message: string) => {
console.log('I have been called with ' + message);
});
object.sendDataToServer('Some Message'); // -> will call the function defined above and log the message passed
Or if you want to call the actual function:
let mySpy = spyOn(object, 'sendDataToServer').and.callThrough();
object.sendDataToServer('Some Message'); // -> will call the actual function on object
Gist:
I spy on get method of my rest service:
spyOn(restService, 'get').and.callFake(function () {
return deferred.promise;
});
The method I am trying to test is myService.getFormData() that returns a chained promise:
function getFormData() {
var getPromise = this.restService.get(endPoint, params, true);
var processedDataPromise = then(successHandle, failHandler);
return processedDataPromise;
}
Back to Jasmine spec, I invoke getFormData function and make assertions:
var processedDataPromise = myService.getFormData();
processedDataPromise.then(function(data) {
expect(data).not.toBeNull();
});
deferred.resolve(testFormData);
$rootScope.$digest();
The Problem:
The above derivative promise (processedDataPromise) does indeed get resolved. However the 'data' passed to it is undefined. Is it anything to do with $digest cycles not doing its job in Jasmine?
Why does Jasmine not pass any data to the above derived promise.?
Further Note: The processedDataPromise is a completely new promise than the get returned promise.
It is a promise for processedData which as we can see is returned by successHandle (Definition not shown) once its parent getPromise gets resolved.
In UI everything works like a Charm.
Sorry for posting the question. The derivative promise indeed got the resolved data I was referring to. The problem was that I was incorrectly accessing the JSON data inside of successHandle.
As a result the 'successHandle' returned null and the the processedDataPromise got back undefined response.
Stupid mistake, very hard to find, but the best part is the learning and understanding of JS Promises.
I'm using Sinon with Mocha to test some expiration date values. I used the same code a few months ago and it worked fine, but somewhere between v1.12.x and v1.17.x, something has changed and I can't seem to find the right path.
let sinon = require('sinon');
describe('USER & AUTHENTICATION ENDPOINTS', function(done) {
beforeEach(function() {
this.clock = sinon.useFakeTimers(new Date().getTime());
return fixtures.load(data);
});
afterEach(function() {
this.clock.restore();
return fixtures.clear(data);
});
context('POST /users', function() { ... }
});
I've tried with and without the new Date().getTime() argument.
I've tried passing in and explicitly calling done().
I've tried removing my fixture load/clear processes.
The end result is always the same:
Error: timeout of 5000ms exceeded. Ensure the done() callback is being called in this test.
Has something changed that I just haven't noticed in the documentation? Do I have some kind of error in there that I can't see?
Any thoughts would be appreciated.
UPDATE
So a little more info here. This clearly has something to do with my code, but I'm at a loss.
If I comment every actual test, the tests run and give me a green "0 passing".
If I run an actual test, even one that just this:
context('POST /users', function() {
it('should create a new user', function(done) {
done();
})
});
I'm right back to the timeout. What am I missing?
Mystery solved. It appears to be a conflict between Sinon and versions of Knex > 0.7.6.
Seems to be because pool2 relies on behavior of setTimeout. Using sinon.useFakeTimers(...) replaces several methods including setTimeout with synchronous versions which breaks it. Can fix by replacing with: clock = sinon.useFakeTimers(Number(date), 'Date');
My original code was written in a world where Knex v0.7.6 was the latest version. Now that it's not everything failed even though the code itself was the same. I used the fix mentioned and things look to be fine.
You are passing done to your describe callback in line 2:
describe('USER & AUTHENTICATION ENDPOINTS', function(done) {
Mocha expects you to invoke it... To get rid of the timeout error, just remove the done parameter from the callback.