why is my test skipped on jest - javascript

I have this test using jest, but the second method is getting skipped, why?
const stringToTest = JSON.stringify({"filename":"9F6148567F8.jpg","id":"ss9:blob-ref:29e4b813a","diskp":"gotchi","mikoId":"e3f813a","content":"gotchi, 18/08/13 at 11:57 AM"});
describe('regex for uri', () => {
it('should match expected URI', () => {
expect(matchUriRE.test(stringToTest)).toBe(true);
});
//below method skipped why?
it('should not be bull or undefined'), () => {
expect(matchUriRE.test(stringToTest)).not.toBeNull;
expect(matchUriRE.test(stringToTest)).not.toBe(null);
expect(matchUriRE.test(stringToTest)).not.toBeUndefined();
};
})
with result:
Test Suites: 1 passed, 1 total
Tests: 1 skipped, 1 passed, 2 total

Simple typo. Remove parenthesis after the test description and place it after closing } on the test.
it('should not be bull or undefined'), () => {
Should be
it('should not be bull or undefined', () => {

it's not the case here but just for future reference in my case it was because i added only tag by mistake
exp:
it.only("test name", () => {})
this will only run this tests and ignore the other tests in the same file

Related

Issue with setting up jest mock

I have the following function that is used within cypress tests for which I want to do unit testing (filterTests.js):
const filterTests = (definedTags, runTest) => {
console.log(`Cypress tags: ${definedTags}`);
let isFound = true;
const includeTag = Cypress.env('INCLUDETAG');
const excludeTag = Cypress.env('EXCLUDETAG');
if (includeTag) {
isFound = definedTags.includes(includeTag);
}
if (excludeTag) {
isFound = ! definedTags.includes(excludeTag);
}
if (isFound) {
runTest();
}
};
export default filterTests;
A test double for Cypress.env needs to be created. I'm not sure if this would technically be considered a stub, mock, fake, dummy, etc..., but the philosophical discussion isn't the focus right now. It looks like in the Cypress world, everything is lumped together under 'mock'.
I started down the path of something like this in the Jest test file:
import filterTests from '../../cypress/support/filterTests';
describe('Something', () => {
jest.mock('Cypress', () => ({
env: {
INCLUDETAG: 'jenkins1'
}
}));
it('Something else ', (done) => {
const tempFunc = () => {
console.log('here a');
done();
};
filterTests(tag, tempFunc);
});
});
But for that I get the error message:
Cannot find module 'Cypress' from 'spec/cypress/filterTestsSO2.test.js'
2 |
3 | describe('Something', () => {
> 4 | jest.mock('Cypress', () => ({
| ^
5 | env: {
6 | INCLUDETAG: 'jenkins1'
7 | }
I believe what is complicating this situation is that Cypress is not explicitly imported in filterTests.js
I think you might just want to set the env value at the top of the test
describe('Something', () => {
Cypress.env(INCLUDETAG, 'jenkins1')
it('Something else ', (done) => {
const tempFunc = () => {
console.log('here a');
done();
};
filterTests(tag, tempFunc); // this function will read the env set above
})
})
Further info - Cypress has a cy.spy() which wraps a method and records it's calls but otherwise leaves it's result the same.
Also cy.stub() which records calls but also provides a fake result.
Jest globals
If you are running the test in Jest, then the Cypress global should be able to be mocked simply by setting it up
global.Cypress = {
env: () => 'jenkins1' // or more complicated fn as test requires
}
Note I expect this will only work with simple cases. Cypress wraps jQuery, Chai and Mocha so they behave slightly differently when a Cypress test runs. If the function you test uses any of those features, even implicitly (like command retry), then Jest will not reproduce the right environment.
My recommendation, test Cypress with Cypress.

Jasmine test case are failing, when testing setTimeout inside function [duplicate]

This question already has an answer here:
How to test code setup with babel configuration(For Library) using Jasmine?
(1 answer)
Closed 1 year ago.
Good Day Everyone,
I am quite new to testing frameworks Jasmine. We have a TS project setup and I am trying to test a function consisting of setTimeout, but it keeps failing. I am trying to use Clock
One Important point I noticed is that I am using babel-loader as soon as I change the webpack configuration to ts-loader. The test case doesn't fail. (Don't know Why 🤷‍♀️). I have checked multiple times but no luck.
UPDATE
I figured out why the test cases are failing but I have no idea why is it happening.
The configurations of babel and ts-loader are correct I just changed the setTimeout to window.setTimeout(in babel-loader) repository and now the test cases are executing successfully🤷‍♀️. This was just a wild guess from Stack Overflow Link.
I added a console statement of setTimeout and window.setTimeout and found that the definitions of both functions are very different. window.setTimeout has a definition(Green circle in the screenshot) that is the same as after we install Jasmine.clock install. ie. HERE
But setTimeout definition(Red circle in the screenshot) is very different(below).
function (/* ...args */) {
return fn.apply(that, arguments);
}
I tried doing the same in ts-loader repository but here setTimeout and window.setTimeout definitions are the same.
Code:
hideToast() {
setTimeout(() => {
this.showToast = false;
}, 5000);
}
Test Spec:
beforeEach(() => {
// Sometimes calling install() will fail for some reason,
// but calling uninstall() first will make it work
jasmine.clock().uninstall();
jasmine.clock().install();
});
afterEach(() => {
jasmine.clock().uninstall();
});
it('should hide toast', () => {
const obj: Car = new Car();
obj.showToast = true; // This value should change after timeout
obj.hideToast(); // Call the component method that turns the showToast value as false
jasmine.clock().tick(5000);
expect(obj.showToast).toBeFalsy(); // Then executes this
});
Any suggestion would be helpful.
With babel-loader(Test case fail's) Screenshot(Branch = "main"):
https://github.com/dollysingh3192/ts-babel-template
With ts-loader(Test cases passed) Screenshot(Branch = "tsloader"):
https://github.com/dollysingh3192/ts-babel-template/tree/tsloader
Example with clock() using a promise that we resolve straight away:
import { Car } from './car';
describe('Car', () => {
beforeEach(() => {
jasmine.clock().uninstall(); // you probably don't need this line
jasmine.clock().install();
});
afterEach(() => {
jasmine.clock().uninstall();
});
it('should hide toast', () => {
const obj: Car = new Car();
obj.showToast = true; // also here, it's redundant, as set to true in constructor
obj.hideToast();
Promise.resolve().then(() => {
jasmine.clock().tick(5000);
expect(obj.showToast).toBeFalsy();
});
});
});
Other ideas on how to do it in this github issue
But let's forget about the simple (and best solution) for a moment and dig a big into the issue. Without the Clock class, we would have to use the done() callback.
In that case, we would have two solutions:
1 - change jasmine.DEFAULT_TIMEOUT_INTERVAL, to be at least 1ms higher than your timeout:
import { Car } from './car';
describe('Car', () => {
beforeEach(() => {
jasmine.DEFAULT_TIMEOUT_INTERVAL = 5001;
});
it('should hide toast', (done) => {
const obj: Car = new Car();
obj.hideToast();
setTimeout(() => {
expect(obj.showToast).toBeFalsy();
done();
}, 5000)
});
});
This works with the done() callback (that might be used while working with async tasks)
and by overriding the jasmine.DEFAULT_TIMEOUT_INTERVAL.
2 - Lower your timeout - by 1 millisecond (yes, 1ms is enough):
import {Car} from './car';
describe('Car', () => {
it('go() works', () => {
const car: Car = new Car();
const returnValue = car.go('vroom');
expect(returnValue).toEqual('vroom');
});
it('should hide toast', (done) => {
const obj: Car = new Car();
obj.hideToast();
setTimeout(() => {
expect(obj.showToast).toEqual(false);
done();
}, 4999);
});
});
Same as before, done callback, but this time we finish 1 millisecond before the Jasmine default timeout and the test will pass (obviously, we need to do it in the class and in the test).
According to the Jasmine docs:

How to mock (change value) of global variables in javascript using jest/sinon etc?

I'm writing test cases for a ts file which contains a global variable like so:
let cachedSecret: any;
const find = () => {
if(cachedSecret){
//return something
} else {
//return something else
}
}
I need to find a way so that for one of the test cases I can mock cachedSecret's value as some string and in the other test case it's value should be null.
I'm using jest and sinon but I haven't been able to find a way to do this.
Thanks
You can use rewire package to mock the variable defined in module scope.
E.g.
index.ts:
let cachedSecret: any;
const find = () => {
console.log('cachedSecret:', cachedSecret, typeof cachedSecret);
if (cachedSecret) {
return 'something';
} else {
return 'something else';
}
};
export { find };
index.test.ts:
import rewire from 'rewire';
describe('63955435', () => {
it('should return something', () => {
const mod = rewire('./');
const revert = mod.__set__('cachedSecret', true);
const actual = mod.find();
expect(actual).toEqual('something');
revert();
});
it('should return something else', () => {
const mod = require('./');
const actual = mod.find();
expect(actual).toEqual('something else');
});
});
unit test result with coverage report:
PASS src/stackoverflow/63955435/index.test.ts
63955435
✓ should return something (202ms)
✓ should return something else (40ms)
cachedSecret: true boolean
console.log src/stackoverflow/63955435/index.ts:4
cachedSecret: undefined undefined
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 4.4s, estimated 11s
npm script:
"test:rewire": "ts-node -O '{\"module\":\"commonjs\"}' node_modules/jest/bin/jest.js",
source code: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/63955435

Display test file name in Mocha output

Is there anyway to have mocha display the name of, or group the output by the test file?
Given two test files, ./test/testFoo.js and ./test/testBar.js I'd like to see something like this when running mocha test:
* testFoo:
Doing X
✓ should return A
✓ even with negative input
Doing Y
✓ should return B
✓ should return C when called with Egyptian hieroglyphs
* testBar:
Doing Z
✓ should return D
(This might be an XY problem. If there are other way to group tests in two levels, I'm just as interested. It's just that the files are already there, as a kind of natural first level group.)
I got tired of there being no solution for this every time I went searching for one and built my own reporter:
https://www.npmjs.com/package/mocha-spec-reporter-with-file-names
That page contains the details but here they are repeated:
install it: npm i -D mocha-spec-reporter-with-file-names
set it at your reporter
cli: npx mocha --reporter './node_modules/mocha-spec-reporter-with-file-names'
config:
// .mocharc.js
const SpecReporterWithFileNames = require('mocha-spec-reporter-with-file-names');
module.exports = {
reporter: SpecReporterWithFileNames.pathToThisReporter,
};
Output currently looks like this:
You should be good using Mocha's describe method to logically group your tests. For the output you desire, the structure of your tests would look like:
/test/testFoo.js
describe('testFoo', () => {
describe('Doing X', () => {
it('should return A', () => {
});
it('even with negative input', () => {
});
});
describe('Doing Y', () => {
it('should return B', () => {
});
it('should return C when called with Egyptian hieroglyphs', () => {
});
});
});
/test/testBar.js
describe('testBar', () => {
describe('Doing Z', () => {
it('should return D', () => {
});
});
});

How to cleanup jest beforeEach and afterEach in a loop

I have a loop that inside has beforeEach and it. Whenever I run, I can see that beforeEach and afterEach functions persist in the loop. How can I remove them?
describe('test', () => {
['1', '2', '3'].forEach(each => {
beforeEach(() => {
console.log(`before ${each}`)
})
it('test 1', () => {
console.log(`test1 ${each}`)
})
it('test 2', () => {
console.log(`test1 ${each}`)
})
})
I'm getting on the console:
before 1
test 1
before 1
test 2
before 1
before 2
test 1
before 1
before 2
test 2
before 1
before 2
before 3
test 1
before 1
before 2
before 3
test 2

Categories