I am trying to test a code snippet using jasmine but its always passing due to Jasmine's it method is being called as asynchronously. Here is my test code
function outer() {
it("| --- BEFORE OUTER ---|", function() {
expect("yes").toEqual("yes");
});
it("outer() is in scope", function() {
expect(typeof outer).toEqual('function');
});
it("inner() is in scope", function() {
expect(typeof inner).toEqual('function');
});
it("a is in scope", function() {
console.log('Why this is running after');
expect(typeof a).toEqual('number');
});
it("b is in scope", function() {
expect(typeof b).toEqual('number');
});
it("c is in scope", function() {
expect(typeof c).toEqual('number');
});
console.log("This is running first");
var a = 1;
function inner() {}
var b = 2;
if (a == 1) {
var c = 3;
}
}
outer();
how to fix this? I want to run it's callback method immediately before running the declaration statements like var a = 1;
Related
I have an if-else statement in a function. I want to test both cases. When the instance is initiated, self.count is set to 1. When I run my test, it goes to the false statement. How can I make self.count = 2 to go into the else statement?
Test:
it('verify change', function () {
spyOn(this.instance, 'change').and.callThrough();
this.instance.change('messageBoard');
expect(this.instance.change).toHaveBeenCalled();
});
Javascript:
self.count = 1;
self.change = function change() {
if(self.count <= 1) {
// do stuff
} else {
// do stuff
}
};
I know I can use this.object.method.and.returnValue() to make a method return a value, but I don't know how to do it with variables.
So it seems i do not need to mock the variables. I can just assign it within the test like:
it('verify change', function () {
this.instance.count = 2; // this would nake it go to the else block
spyOn(this.instance, 'change').and.callThrough();
this.instance.change('messageBoard');
expect(this.instance.change).toHaveBeenCalled();
});
I want to do something like this:
var build= (function(){
//my function body
})();
function test(){
//somthing then call build
build() //i want to call build function again in my code
}
How can I do this?
I tried this in angular:
var buildRoot = (() => {
$SubNode.get({
TypeID: vendorAdminService.NodeType.Category
}, function(data: vendorAdminService.IGetNodeParameters) {
$scope.ProductTree = data.TreeNodeModelItem;
$scope.AjaxLoading = false;
}, function(err) {
// alert(err)
})
})();
$mdDialog.show(confirm).then(function() {
$Category.Remove(node.ID)
buildRoot
}, function() {
});
but it does not work.
Anybody can guide me??
You need to return a function in your IIFE.
If you IIF is not trivial and has many functionalities you could also consider using Reveal Module Pattern.
var build = (function() {
var f = function() {
console.log('hello');
};
f();
return f;
})();
function test() {
build();
}
test();
Just use a named function.
Your IIFE needs to return a function, for later calling. But then is no need for an anonymous function.
function build() {
//my function body
}
or
var build = function () {
//my function body
};
var build = (function() {
var init = function() {
// magic code
};
return {
init: init
}
}());
function test() {
build.init()
}
test();
You include all your functionalities inside your build object, and you'll be able to call them as soon as you return them from inside that object. This effectively is called the revealing module pattern
For more information, read this
I see that there are missing semi-colons ";"
$mdDialog.show(confirm).then(function() {
$Category.Remove(node.ID);
buildRoot();
}, function() {
});
Given a data structure that satisfies some invariants, I would like to test the state of an instance of the data structure after various operations. What is the best way to do this?
describe('data-structure', function() {
var x;
beforeEach(function() {
x = getDataStructure();
});
describe('satisfies invariants', function() {
// run tests on 'fresh' x
it('should ...', function() {
// ...
});
// ...
});
describe('operation 1', function() {
it('should preserve invariants', function() {
x.doSomething();
// run 'satisfies invariants' tests on modified x
});
});
});
I thought about using an afterEach hook, but I do not think x is preserved there?
afterEach(function() {
// somehow run 'satisfies invariants' test
});
It maybe be that I can refactor 'satisfies invariants' into a method, but it would be nice if mocha could report which invariant-tests failed for each operation, e.g.
data-structure
satisfies invariants
should satisfy invariant 1 ...
...
operation 1
should satisfy invariant 1 ...
...
operation 2
should satisfy invariant 1 ...
...
Edit
Using the structure
describe('data-structure', function() {
var x;
describe('satisfies invariants', function() {
afterEach(function() {
it('should satisfy invariant 1', function() {
// x.value === a again
// ...
});
// ...
});
it('should work after operation 1', function() {
x = getDataStructure(); // x.value === a
x.operation1(); // x.value === b
});
it('should work after operation 2', function() {
x = getDataStructure();
x.operation2();
});
// ...
});
});
does not seem to preserve the changes to x.
It follows an example, let me know if I forget something of what we have discussed:
var assert = require('assert');
describe('data-structure', function() {
var x;
beforeEach(function() {
// freshly created data structure for each describe block below
x = getDataStructure;
});
describe('satisfies invariants', function() {
after(function() {
// it executes those tests only once after all the it block below
assert(x); // put your tests here
});
it('op 1.1', function() {
do_something_on(x);
});
it('op 1.2', function() {
// keep in mind that x is the same instance of the previous test
do_something_else_on(x);
});
// so on
});
describe('satisfies something else', function() {
// here you have a new instance of x, because of the outer beforeeach
after(function() {
// it executes those tests only once after all the it block within this describe block
assert(x); // put your tests here
});
it('op 2.1', function() {
do_something_on(x);
});
it('op 2.2', function() {
// keep in mind that x is the same instance of the previous test, but not the one used in 1.2
do_something_else_on(x);
});
// so on
});
// so on
});
This piece of code should give you an idea of which instance is accessible and where.
If it lacks something, let me know and I'll have a go to fix it.
The Problem
Mocha does not support putting it inside a hook like you do in your last snippet. (afterEach is a hook). In some trivial cases you may get the desired behavior but that's just luck. Once you move on to more complicated test suites, you won't get the behavior your expect.
Moreover, I suggest that afterEach is the wrong place for that kind of test. You should use the hooks only to setup and tear down your test environment and not for performing assertions on the state of your code. Mocha treats any failure in a hook as "the test suite is broken, abort!!" rather than as a test failure. Look at this example, for instance:
var assert = require('assert');
describe("test", function () {
var x;
beforeEach(function () {
x = { foo: 'something' };
});
afterEach(function () {
assert(x.foo === 'something');
});
it("one", function () {});
it("two", function () {
x.foo = 'something else';
});
it("three", function () {});
});
In theory there's no reason test three should not run but when the failure occurs in the afterEach hook after test two is run, Mocha will just stop running tests there. The output (omitting the final stack trace) is:
test
✓ one
✓ two
1) "after each" hook
2 passing (14ms)
1 failing
Note how two is marked as passing but the hook failed. And note how three is never even attempted. As soon as there is a failure in a hook, Mocha stops right there.
The Solution
You should just create a function that you call from each test to test your invariants. For instance:
var assert = require('assert');
describe("test", function () {
var x;
beforeEach(function () {
x = { foo: 'something' };
});
function testInvariant() {
assert(x.foo === 'something');
}
it("one", function () {
testInvariant();
});
it("two", function () {
x.foo = 'something else';
testInvariant();
});
it("three", function () {
testInvariant();
});
});
If you run Mocha on the code above, you'll get (again, omitting the final stack trace):
test
✓ one
1) two
✓ three
2 passing (10ms)
1 failing
two was marked as failed and Mocha moved on to run three, which was successful.
If you don't want to write testInvariant() in each test you could create a function that adds it for you. For instance:
var assert = require('assert');
describe("test", function () {
var x;
beforeEach(function () {
x = { foo: 'something' };
});
function makeTest(name, fn) {
it(name, function () {
fn();
assert(x.foo === 'something');
});
}
makeTest("one", function () {
});
makeTest("two", function () {
x.foo = 'something else';
});
makeTest("three", function () {
});
});
This produces the same output as the previous code snippet.
The following test code, written using Mocha.js fails. I expect the someVal to be increased 3 times and equal 3 in the last test. The issue came up in more complex scenario where I used value set in outer before block to set up another in inner beforeEach block. Simplified case:
describe('increasing 3 times', function() {
before(function() {
this.instanceThis = this;
return this.someVal = 0;
});
beforeEach(function() {
return this.someVal += 1;
});
return describe('going deeper', function() {
before(function() {
return this.someVal += 1;
});
beforeEach(function() {
return this.someVal += 1;
});
return it('has increased someVal to 3', function() {
return this.someVal.should.equal(3);
});
});
});
Explanation
I don't know of any version of Mocha that would run the code you show in your question without error. For your code to work, it would have to be written like this:
require("chai").should();
describe('increasing 3 times', function() {
before(function() {
this.someVal = 0;
});
beforeEach(function() {
this.someVal += 1;
});
describe('going deeper', function() {
var parent_ctx = this.parent.ctx;
before(function() {
parent_ctx.someVal += 1;
// The line above is equivalent to this:
// this.test.parent.ctx.someVal += 1;
});
beforeEach(function() {
parent_ctx.someVal += 1;
});
it('has increased someVal to 3', function() {
parent_ctx.someVal.should.equal(3);
// The above line is equivalent to this:
// this.test.parent.parent.ctx.someVal.should.equal(3);
});
});
});
Inside the function passed to describe and the functions passed to the hooks of a describe block (before, beforeAll, etc.) the value of this is a "context" object which is the same for the describe and all of its own hooks (not the hooks of other describe calls nested in it). So when you assign to this, it assigns to the context. If you want to access this context inside nested calls to describe or in tests you have to walk up the tree of describe and test objects.
Solution
I would do it exactly the same way Second Rikudo suggested: use a variable scoped to your uppermost describe call. For the sake of completeness:
require("chai").should();
describe('increasing 3 times', function() {
var someVal;
before(function() {
someVal = 0;
});
beforeEach(function() {
someVal += 1;
});
describe('going deeper', function() {
before(function() {
someVal += 1;
});
beforeEach(function() {
someVal += 1;
});
it('has increased someVal to 3', function() {
someVal.should.equal(3);
});
});
});
this is not what you think it is. this gets redefined in every function() {} block (unless Mocha calls them in some specific way I'm not familiar with).
What you want is to use scope in your advantage:
describe('increasing 3 times', function() {
var someVal; // Initialization.
before(function() {
someVal = 0; //No need to return from before()
});
beforeEach(function() {
someVal += 1;
});
describe('going deeper', function() {
before(function() {
someVal += 1;
});
beforeEach(function() {
someVal += 1;
});
return it('has increased someVal to 3', function() {
someVal.should.equal(3);
});
});
});
Also, you don't need to return so much. In fact, you almost never have to return in test code.
I did a sample example on Meteor.setTimeout() using Meteor. In this example i get an error. I didn't have any idea about this.So please see the below code,error and suggest me how to do?
Error :
Exception in setTimeout callback: TypeError: undefined is not a function
at _.extend.withValue (http://localhost:3000/packages/meteor.js?8ec262df25783897eaad01255bc8bd1ca4e78b24:773:17)
at http://localhost:3000/packages/meteor.js?8ec262df25783897eaad01255bc8bd1ca4e78b24:358:45
at http://localhost:3000/packages/meteor.js?8ec262df25783897eaad01255bc8bd1ca4e78b24:801:22
JS Code :
if (Meteor.isClient)
{
Meteor.setTimeout(Test("10"), 1000);
Meteor.setInterval(Test1, 1000);
Template.hello.greeting = function ()
{
return "Welcome to timerapp.";
};
Template.hello.events
({
'click input' : function ()
{
// template data, if any, is available in 'this'
if (typeof console !== 'undefined')
console.log("You pressed the button");
//Test();
}
});
}
function Test(x)
{
console.log("*** Test() ***"+x);
}
function Test1()
{
console.log("*** Test1() ***");
}
if (Meteor.isServer)
{
Meteor.startup(function ()
{
// code to run on server at startup
});
}
The problem is that setTimeout expects a function as a first parameter but you are passing the result of evaluating Test("10") which is "undefined".
You can solve the issue by wrapping your call to Test1 in an anonymous function:
Meteor.setTimeout(function(){Test("10");}, 1000);