Scoping in Jest when mocking functions - javascript

I have a test where I'm trying to mock a component in two different situations. When I use jest.fn. It almost looks like the first test is just taking the value from the second.
describe('tests', () => {
let sampleArray = new Array()
Array.prototype.test = function() {
return this.innerArray()
}
describe('empty', () => {
sampleArray.innerArray = jest.fn(() => [])
it('testArray is empty', () => {
expect(sampleArray.test().length).toEqual(0)
})
})
describe('not empty', () => {
sampleArray.innerArray = jest.fn(() => ['test'])
it('testArray is not empty', () => {
console.log(sampleArray.innerArray())
expect(sampleArray.test().length).toEqual(1)
})
})
})
When I console.log I get the array I expect from innerArray, but it just looks like it doesn't use it.
FAIL test/sample.test.js
tests
empty
✕ testArray is empty (8ms)
not empty
✓ testArray is not empty (4ms)
● tests › empty › testArray is empty
expect(received).toEqual(expected)
Expected value to equal:
0
Received:
1
edit: If I place it inside the it scope, it works. But why can't I do it in the describe scope?
describe('tests', () => {
let sampleArray = new Array()
Array.prototype.test = function() {
return this.innerArray()
}
describe('empty', () => {
it('testArray is empty', () => {
sampleArray.innerArray = jest.fn(() => [])
console.log(sampleArray.innerArray())
expect(sampleArray.test().length).toEqual(0)
})
})
describe('not empty', () => {
it('testArray is not empty', () => {
sampleArray.innerArray = jest.fn(() => ['test'])
expect(sampleArray.test().length).toEqual(1)
})
})//works

Unless you specifically expect the array to be shared among all your tests, you should set it up as follows:
Array.prototype.test = function() {
return this.innerArray()
}
describe('tests', () => {
let sampleArray
beforeEach(() =>
sampleArray = new Array()
})
// tests...
});

Related

How to use jest to test an asynchronous epic with axios-mock-adapter mock data?

when I run testing code, actual$ returns an empty array, expected returns the mock data.
the reason is api.ugc.wishlist.getAllFolders() is asynchronous.
how should I write the test?
//testing code:
describe('wishlist select', () => {
describe('dispatch a correct action of load', () => {
it('select getAllFolders successfully', () => {
getTestScheduler().run(({ cold, expectObservable }) => {
const action$ = ActionsObservable.from(
cold('(a|)', {
a: actions.load.start(),
})
);
const state$ = new StateObservable<IState>(new Subject(), initialState);
const expected$ = {
a: actions.load.done(toFolders(select.items)),
};
const actual$ = load(action$, state$, dependencies);
// the actual$ return an empty array.
expectObservable(actual$).toBe('(a|)', expected$);
});
});
});
});
// load epic code:
export const load: IEpic = (action$, state$, { api }) =>
action$.pipe(
ofType(actions.load.start.getType()),
mergeMap(() => {
return from(api.ugc.wishlist.getAllFolders()).pipe( // get mock dara from axios-mock-adapter
mergeMap(response => {
const { items } = response.data;
return of(actions.load.done(toFolders(items)));
})
);
})
);

testing module functions with jest

I have a module that looks like this:
const config = require('config')
const isActive = config.get('isActive')
const infoMap = new Map()
const set = (key, value) => {
infoMap.set(key, value)
}
const get = (key) => infoMap.get(key)
module.exports={set, get}
and a test where I test the stuff:
let get
let set
beforeEach(() => {
jest.mock('config')
mockIsActive = require('config').get.mockReturnValueOnce(true)
get = require('../cache/mymap').get
set = require('../cache/mymap').set
})
describe('The map', () => {
describe('when data is added', () => {
set('testKey', "testData")
it('should contains the data', async () => {
const dataFromMap = get('testKey')
assert("testData", dataFromMap)
})
})
})
It fails when the set is called with:
set is not a function
Strange is that get works without problems.
You must call the set function inside the it function, otherwise it is not yet defined:
describe('when data is added', () => {
it('should contains the data', async () => {
set('testKey', "testData")
const dataFromMap = get('testKey')
assert("testData", dataFromMap)
})
})
beforeEach runs before each it function, not before describe. This is also why get does work in your example - it is inside the it function.

How to extract and use a string value returned from cy.wrap()

Cypress sees my returned strings as objects, so I'm trying to use cy.wrap() to resolve the value as string.
I have a cypress custom command, like so:
Cypress.Commands.add('emailAddress', () => {
var emailAddress = 'testEmail-' + Math.random().toString(36).substr(2, 16) + '#mail.com';
return cy.wrap(emailAddress);
})
That I need the return value as a sting in my test:
beforeEach(() => {
var user = cy.emailAddress().then(value => cy.log(value)); // testEmail-123#mail.com
logonView.login(user) // object{5}
})
How do I use the string value for my login and elsewhere in my test?
Something like: logonView.login(user.value)
... but this doesn't work?
In Cypress, you cannot return value like this
var user = cy.emailAddress().then(value => cy.log(value));
Instead, you get the return value in the then .then callback:
cy.emailAddress().then((value) => {
logonView.login(user)
});
So, for you test, you can instead do the following:
describe("My test", () => {
beforeEach(() => {
cy.emailAddress().then((value) => {
logonView.login(user)
});
});
it("should have logged into the App", () => {
// Write your test here
});
});
Or use a variable in the before each block, and access it later in the test:
describe("element-one", () => {
let user;
beforeEach(() => {
cy.emailAddress().then((value) => (user = value));
});
it("it should have user value", () => {
expect(user).to.includes("testEmail");
});
});

how to check function is called or not in react js?

I am trying to test my service which have one function saveWithoutSubmit
export const saveWithoutSubmit = async (
values,
orderId,
taskId,
fseMsisdn,
updateTaskListAfterFilter
) => {
var obj = {
remarks: values.remarks,
requestedBy: localStorage.getItem("msisdn")
};
try {
const response = await sendPostRequest(`${API_TASK_URL}closeSr`, {
...obj,
saveWithoutSubmit: true
});
if (response && response.data && response.data.status.code !== "200") {
error(response.data.result.message);
} else {
console.log(response);
success(response.data.status.message);
updateTaskListAfterFilter();
}
} catch (e) {
if (e.response && e.response.data) {
console.log(e.response.data.message);
error(e.response.data.status.message);
}
}
};
I want to check success or error method is called or not ? or updateTaskListAfterFilter is called or not?
I tried like this
https://codesandbox.io/s/ecstatic-currying-5q1b8
describe("remark service test", () => {
const fakeAxios = {
get: jest.fn(() => Promise.resolve({ data: { greeting: "hello there" } }))
};
it("save without sumit", () => {
const updateTaskListAfterFilter = () => {};
saveWithoutSubmit({}, updateTaskListAfterFilter);
expect(updateTaskListAfterFilter).toBeCalled();
});
});
can you please suggest how i will test async methods or post request (using mook data)??
so that my test cases will be passed.
I want to check if I got success from promise my success method will be called else error
any update ?..!!
update
https://codesandbox.io/s/ecstatic-currying-5q1b8
it("save without sumit", async () => {
const sendPostRequest = jest.fn(() =>
Promise.resolve({ data: { greeting: "hello there" } })
);
const updateTaskListAfterFilter = () => {};
saveWithoutSubmit({}, updateTaskListAfterFilter);
expect(updateTaskListAfterFilter).toBeCalled();
});
it("save without sumit", async () => {
const sendPostRequest = jest.fn(() =>
Promise.resolve({ data: { greeting: "hello there" } })
);
const mockUpdateTaskListAfterFilter = jest.fn();
const updateTaskListAfterFilter = () => {};
saveWithoutSubmit({}, updateTaskListAfterFilter);
expect(updateTaskListAfterFilter).toBeCalled();
await wait(() => {
expect(mockUpdateTaskListAfterFilter).toBeCalled();
});
});
You should change it("save without sumit", () => { to it("save without sumit", async () => {.
Then you usually use jest.fn() to create a mock function that you will give to another function or component.
Finally, await the mock function to be called:
await wait(() => {
expect(mockUpdateTaskListAfterFilter).toBeCalled();
});
Alternatively, you can await some other event that you know will occur before your mock is called, like some other mock getting called or something appearing on the page, and then check that your mock was called.

Enzyme restore getEelemenById before each test

I stub getElementById in beforeEach, and want to restore it before another test and stub again with anothter returns value. Because now I recieve error
TypeError: Attempted to wrap getElementById which is already wrapped
let loginUrl = 'loginUrl'
const url = '/app/auth'
const textContent = `{"${loginUrl}":"${url}"}`
let htmlDecode
describe('identityServer', () => {
beforeEach(() => {
htmlDecode = sinon.stub().returns(textContent)
sinon.stub(document, 'getElementById').returns({textContent})
sinon.stub(htmlEncoder, 'Encoder').returns({htmlDecode: () => htmlDecode})
identityServerModel()
})
it('should return correct model for IdentityServer', () => {
window.identityServer.getModel().should.deep.equal({[loginUrl]: url})
})
})
describe('identityServer', () => {
beforeEach(() => {
htmlDecode = sinon.stub().returns(textContent)
sinon.stub(document, 'getElementById').returns({innerHTML: textContent})
sinon.stub(htmlEncoder, 'Encoder').returns({htmlDecode: () => htmlDecode})
identityServerModel()
})
it('should return correct model using serialization HTML from innerHTML property when textContent is undefined', () => {
window.identityServer.getModel().should.deep.equal({[loginUrl]: url})
})
})
Try add:
afterEach(() => {
document.getElementById.restore();
})
into every describe(...).

Categories

Resources