In my controller I've a statement assigning an empty function in a variable based on a condition.
var vm = this;
vm.emptyFunction = angular.isFunction(callback) ? callback : function() {};
How can I test that this vm.emptyFunction is actually an empty function?
Things which didn't work:
expect(vm.emptyFunction).toEqual({});
expect(vm.emptyFunction()).toEqual({});
expect(vm.emptyFunction).toEqual(() => {}); //using typescript
Thing which work is:
expect(vm.emptyFunction).toEqual(jasmine.any(Function));
But this will get valid for any function definition.
The only thing I can think of is to use the same reference to the same empty function.
var emptyFunction = function {};
and then use
vm.emptyFunction = angular.isFunction(callback) ? callback : emptyFunction;
Then test
expect(vm.emptyFunction).toEqual(emptyFunction);
Related
I have created this spy using spyOn
it("spyon ", () => {
const searchChangeEmitSpy = spyOn(Adders.countlist,"add");
expect(searchChangeEmitSpy.calls.count()).toEqual(2);
});
and inside Adder class I have the following function
countlist(){ const i =0;
this.quoteList.forEach(element => {
console.log(element);
this.add(4,i++);
});
}
length of quoteList array is 2
what I am getting as a result
Error: : add() method does not exist
I don't think you can directly spy on the function of the class Adders like this, instead spy on the prototype or create an instance of the class and spy on that. I would use two spies and implement it like this:
it("spyon", () => {
const countlistSpy = spyOn(Adders.prototype, 'countlist');
const addSpy = spyOn(Adders.prototype, 'add');
// call your function / trigger something that calls the function
expect(countlistSpy).toHaveBeenCalledTimes(1);
// more expectations here
});
Or with an instance of the class in the beforeEach block you can define your instance like this:
let adder: Adders = new Adders();
And then your test would look like this:
it("spyon", () => {
const countlistSpy = spyOn(adder, 'countlist');
const addSpy = spyOn(adder, 'add');
// call your function / trigger something that calls the function
expect(countlistSpy).toHaveBeenCalledTimes(1);
// more expectations here
});
With the help of Fabian answer, I able to debug and solve my problem. Actually, I need to trigger the function inside the class on which I was spying. after doing so, it gave me the expected output.
test case
it("spyOn countList add()", () => {
const searchChangeEmitSpy = spyOn(Adders,"add");
Adders.addNewQuote("This is my second post");
Adders.countlist(0);
expect(searchChangeEmitSpy.calls.count()).toEqual(2);
});
function inside the class to be spied
countlist(i:number){
this.quoteList.forEach(element => {
console.log(element);
this.add(4,i++);
});
//return i;
}
I'm adding Jasmine to a large project in order to add tests to that project's javascript. Normally I use Ruby and I'm a little out of my element here.
I have a class, that has a function and I want to create a spy for it so that it returns a certain value during one of my tests. Here's a summary of the code:
class #MyKlass
current_location = ->
window.location.host
verify_domain: () ->
domain_filter = current_location()
domain_list = /example\.com/i
#valid_domain = domain_filter.match(domain_list)?
So how would I do something like this?
it("verifies domains", function() {
spyOn(MyKlass, 'current_location').and.returnValue("example");
var myKlass = new MyKlass();
expect(myKlass.verify_domain()).toEqual(true);
});
So it turns out that this was a function on an instance of the class- which I had just missed somehow in the code. Here's the abbreviated solution:
describe('MyKlass', function() {
myKlass = null
beforeEach(function() {
myKlass = new MyKlass()
});
it('returns true for our domains', function() {
spyOn(myKlass, 'verify_domain').and.returnValue(true);
expect(myKlass.verify_domain()).toBe(true);
});
I was trying to define one sort of global variable which value will be reflecting in 2/3 different templates (directives). For that I used angular factory as follows:
app.factory('MyService', function ($http) {
return {
firstNumber: function (){
//return selectedNumber = "200";
var selectedNumber = "";
var selectedNumber = $http.get("/count.do").success(function (data) {
console.log('First Number: ', data[0].count)
});
return selectedNumber;
}
};
});
As you can see 'selectedNumber' is that common variable. Problem is when I am hard coding the value as "200" and from controller calling as follows:
//Init Number
$scope.selectedNumber= MyService.firstNumber();
This whole process is working fine. But as soon as I am trying to get the value from back end (which you can see above) getting {} object.
I did some research on this and understanding that my concept on Angular object and String manipulation is not clear...can anyone please help me to understand the mistake I am doing and to resolve this situation.
Well, i got my expected outcome by using 'callback' service as follows:
In my factory i just called the '$http.get':
app.factory('MyService', function ($http) {
return {
firstNumber: function (){
$http.get("/count.do").success(callback);
}
};
});
And then from controller i received the data and assigned as follows:
//Init Number
MyService.firstNumber(function(data) {
$scope.selectedNumber = data[0].count;
});
I don't know whether it is a good solution or what, will really appreciate for any comment on this solution plz.
Thanks
OK, I'm obviously not understanding how functions are used in javascript. Given the below code snippet, mozilla firefox is telling me that calcUpper is not defined. Basically I want to define a function and use that function later on in the view on different fields. I tried moving the function definition outside of the kendo model, but with no better results. Can someone show me how I can achieve this?
var viewModel = kendo.observable({
calcUpper: function (fieldName) {
var value = this.get(fieldName);
if (value == "")
return "";
else
return parseInt(value) - 1;
},
jobNum: '',
SRCPerif: '',
SRCOnTargetUpper: calcUpper('SRCPerif'),
SRCOnTargetLower: '',
SRCConcernUpper: calcUpper('SRCOnTargetLower'),
//...other fields...
});
I have a problem accessing for loop variable inside my AJAX functions. Below is my code.
for (var x; x<=8; x++){
$('#sumbit_button'+x).bind('keyup paste', function(value){
var val = $(this).val();
$.post('index.php', {val : val }, function(data){
$('#sumbit_this_'+x).html(data);
verify_error(value);
});
});
}
The line
$('#sumbit_button'+x).bind('keyup paste', function(x){ ... }
Means that your previously defined variable x is overriden in local function scope by function argument x which is actually the keyup or paste event. If you want to keep reference to x, rename function(x){...} to something more logical, like function(event) {...} or do not use function argument at all if you don't need it function(){...}.
It would be a good idea to read more about how jQuery and Javascript event handlers work.
Update
Your current version of the script will not work either because you're still passing jQuery event object to the verify_error instead of x. The problem is that you do not pass x when declaring an event handler, you're declaring a new variable, which is currently called value. Delete the variable value from $('#sumbit_button'+x).bind('keyup paste', function(value){...} and simply pass 'x' to the verify_error as in the first version of your script.
You've overwritten the x by your function(x)
Try renaming x in function(x) to something else like function(y) or whatever that make sense.
for (var x; x<=8; x++){
$('#sumbit_button'+x).bind('keyup paste', function(){
var val = $(this).val();
$.post('index.php', {val : val }, function(data){
$('#sumbit_this_'+x).html(data);
verify_error(x);
});
});
}