I have to make a test for a vue instance using jest and the test includes a confirm pop up, question is how to simulate click on "Yes" in the pop up. I was trying to use:
window.confirm = jest.fn(() => true);
and:
window.confirm = () => true;
and inventing something like that:
wrapper.confirm = () => true;
But no luck, maybe someone had similar problem?
Since we're running the tests in Nodejs we can reference confirm as global.confirm and If we want to test the function add if it adds 2 whenever confirm returns true we can do this:
const add = require('./add');
describe('add', () => {
describe('confirm returning true', () => {
let result;
beforeAll(() => {
// we define confirm to be a function that returns true
global.confirm = jest.fn(() => true);
result = add(1);
});
it('should call confirm with a string', () => {
expect(global.confirm).toHaveBeenCalledWith(
expect.any(String),
);
});
it('should add two', () => {
expect(result).toBe(3);
});
});
describe('confirm returning false', () => {
let result;
beforeAll(() => {
// we define confirm to be a function that returns false
global.confirm = jest.fn(() => false);
result = add(1);
});
it('should call confirm with a string', () => {
expect(global.confirm).toHaveBeenCalledWith(
expect.any(String),
);
});
it('should NOT add two', () => {
expect(result).toBe(1);
});
});
});
online working example
Related
I would like to mock value ENV_JWT_ENABLED peer test. I would like to use new value A in first test and new value B in second test. But I am getting still foo from global mock.
My current solution not working.
import { JwtAuthGuard } from './jwt-auth.guard';
jest.mock('const/env', () => ({
ENV_JWT_ENABLED: 'foo'
}));
describe('test', () => {
it('A', () => {
jest.mock('const/env', () => ({
ENV_JWT_ENABLED: 'new value A'
}));
const instance = new JwtAuthGuard(); // will print foo inside
});
it('B', () => {
jest.mock('const/env', () => ({
ENV_JWT_ENABLED: 'new value B'
}));
const instance = new JwtAuthGuard(); // will print foo inside
});
});
jest always prefered global vs within block, better using mockImplementationOnce with
mockImplementation provide you to mock value based on its call.
you can refer https://jestjs.io/docs/en/mock-function-api#mockfnmockimplementationoncefn chaining of mock for fn.
import { JwtAuthGuard } from './jwt-auth.guard';
jest.mock('const/env', () => {
return {
ENV_JWT_ENABLED: jest
.fn()
.mockImplementation()
.mockImplementationOnce(() => {
return 'new value A';
})
.mockImplementationOnce(() => {
return 'new value B';
})
};
});
describe('test', () => {
it('A', () => {
const instance = new JwtAuthGuard(); // will print new value A inside
});
it('B', () => {
const instance = new JwtAuthGuard(); // will print new value B inside
});
});
jest.mock at test level cannot affect top-level imports. jest.isolateModules or jest.resetModules can be used in conjunction with require or dynamic import to provide test-specific module mocks:
it('A', () => {
jest.isolateModules(() => {
jest.mock('const/env', () => ({
ENV_JWT_ENABLED: 'new value A'
}));
const { JwtAuthGuard } = require('./jwt-auth.guard');
const instance = new JwtAuthGuard();
});
});
I am using firebase admin and I am trying to write some unit tests for my code.
Since admin is injected in my function I figured I could mock a very simple object like this:
admin = {
get auth () {
return {
updateUser: () => {
return true;
},
createUser: () => {
return true;
},
getUser: () => {
throw Error('no user');
}
};
}
};
Then in a particular test I can stub the functions. Here is what I have done so far:
// stubbed functions
sinon.stub(admin, 'auth').get(() => () => ({
updateUser: () => ({ called: true }),
getUser: () => (userRecord),
createUser: () => ({ called: false })
}));
and those are working fine (I can see with my logs).
However in my test I would also want to check if createUser has been called at all.
I thought I could set up a spy on the createUser function, but so far I can't really get it to work.
Here is what I have been trying (with a bunch of variation always failing):
it.only('should update a user', async () => {
const userRecord = mockData
sinon.stub(admin, 'auth').get(() => () => ({
updateUser: () => ({ called: true }),
getUser: () => (userRecord),
createUser: () => ({ called: false })
}));
const spy = sinon.spy(admin, 'auth', ['get']); // this is not working
const user = await upsertUser(data, firestore, admin);
expect(user).toEqual(data.userDataForAuth); // this one is ok
sinon.assert.calledOnce(spy.get); // this throws an error
});
the bit of code I am trying to test (which is the upsert function is this:
// in my test exisiting user is not null (the stub `getUser` is returning a object
if (existingUser != null) {
try {
await admin.auth().updateUser(uid, userDataForAuth);
return userDataForAuth;
} catch (error) {
console.log('error', error);
throw Error('error updating user');
}
}
I am not even sure this is the best approach, happy to change it if there is a better one!
I am trying to write a unit test for a function that does an async call, but it doesnt seem to alter the data prop, maybe I am doing something wrong.
Check the code below:
getSomething() {
MyService.getThis().then(
response => {
this.status = true;
}
).catch(error => {})
}
TestCase:
describe('test', () => {
beforeEach(() => {
// To ignore the created hook, but this doesnt work, any idea?
spyOn(CustomerData, 'created');
spyOn(MyService, 'getThis').and.returnValue(Promise.resolve(list));
});
wrapper = shallowMount(MyComponent, {
propsData: {
data: {}
},
});
it('should work', () => {
wrapper.vm.getSomething();
expect(wrapper.vm.status).toBeTruthy();
});
});
}
The status should be true, but it is false, but if I print the value of status in the getSomething() function it is indeed true. I have no idea what the issue can be.
update:
In the test case I wrote
it('should work', async () => {
await wrapper.vm.getSomething();
expect(wrapper.vm.status).toBeTruthy();
}
and this seems to work. Is this a good way to solve it? Would love to hear other solutions.
Also I am very interested if it is possible to ignore the created hook, I havent been able to figure that out yet.
Code that running inside getSomething() is asynchronous. MyService.getThis() returns promise, and its execution takes time, in case if you fetching some data from remote serivce.
So first of all you need to return promise from getSomething()
getSomething() {
return MyService.getThis()
.then(response => { this.status = true; })
.catch(error => {})
}
And inside the test you need to return promise outside, to let jest know that your test is asynchronous.
it('should work', () => {
return wrapper.vm.getSomething().then(() => {
expect(wrapper.vm.status).toBeTruthy();
});
});
Or as you mentioned in the edited part you can use async version:
it('should work', async () => {
await getSomething();
expect(wrapper.vm.status).toBeTruthy();
});
I am trying to mock the pg promise library. I want to be able mock return whether the promise rejects or resolves. Here is an example function and test:
const pgp = require('pg-promise')({});
const someFunc = callback => {
const db = pgp('connectionString');
db
.none('create database test;')
.then(() => {
callback(null, 'success');
})
.catch(err => {
callback(err);
});
};
module.exports = {
someFunc
};
And i wanna test it like so:
const { someFunc } = require('./temp');
let pgp = require('pg-promise')({
noLocking: true
});
// HOW TO MOCK?
describe('test', () => {
beforeEach(() => {
jest.resetModules();
jest.resetAllMocks();
});
it('should test', () => {
let db = pgp('connectionString');
// how to mock this?
db.none = jest.fn();
db.none.mockReturnValue(Promise.reject('mock'));
const callback = jest.fn();
someFunc(callback);
return new Promise(resolve => setImmediate(resolve)).then(() => {
expect(callback.mock.calls.length).toEqual(1);
});
});
});
You can mock the pgp object with a dumb mock like so:
const { someFunc } = require('./temp');
let pgp = jest.fn(() => ({
none: jest.fn(),
})
jest.mock('pg-promise') // Jest will hoist this line to the top of the file
// and prevent you from accidentially calling the
// real package.
describe('test', () => {
beforeEach(() => {
jest.resetModules();
jest.resetAllMocks();
});
it('should test', () => {
let db = pgp('connectionString');
db.none.mockRejectedValue('mock'); // This is the mock
const callback = jest.fn();
someFunc(callback);
return new Promise(resolve => setImmediate(resolve)).then(() => {
expect(callback.mock.calls.length).toEqual(1);
});
});
});
Its an old question, but here is a new answer:
You can have a look at pg-mem, a library I released recently which emulates an in-memory postgres instance.
It supports most of the usual SQL queries (but will fail on less frequent syntaxes - file an issue if you encounter such a situation).
I wrote an article about it here
For your use case, see the this section
I am testing a angular component and the code is
ngOnInit(): void {
this.getNar();
}
getNar(): void {
let self = this;
this.dashboardService.getNar().subscribe(
res => self.narIds = res.narIds,
error => self.error = error,
function () {
self.narIds.forEach(element => {
// Some Code
});
}
);
}
The Service provider for this i.e Dashboard Service is
getNar(): Observable<any> {
return this.http.get(Config.Api.GetNar + '1/nar').map((res: Response) => res.json());
}
And my Test cases are:
let res = '"narIds":[{"id":1,"narId":"104034-1","narName":"SDLC Platform"},{"id":2,"narId":"64829-1","narName":"EMS-EMS"}]';
describe('Application Health Component', () => {
beforeEach( async(() => {
TestBed.configureTestingModule({
providers: [MockBackend, DashboardService],
imports: [ChartsModule, SlimScrollModule, HttpModule],
declarations: [CompletedFilterPipe, ApplicationHealthComponent]
})
.compileComponents()
.then(createComponent);
}));
it('should call the getNar when ngOnInit is called', async(() => {
spyOn(dashboardService, 'getNar').and.returnValue(Observable.of(res));
comp.ngOnInit();
expect(dashboardService.getNar).toHaveBeenCalled();
}));
});
function createComponent() {
fixture = TestBed.createComponent(ApplicationHealthComponent);
comp = fixture.componentInstance;
dashboardService = fixture.debugElement.injector.get(DashboardService);
};
The problem I am getting is the test case gives an error that forEach is undefined.
The error message is not that forEach function is not defined, it's that your object "self.narIds" is undefined. Fairly sure this is due to the way you declared your onComplete function in Observable.subscribe
related to this Rx Subscribe OnComplete fires but cannot use the data
change your
function () {
self.narIds.forEach(element => {
// Some Code
});
code to
() => {
self.narIds.forEach(element => {
// Some Code
});