How to run jest test inside other test block? - unit-testing

For example I have 2 test, how can I test one depend on another one?
Sometimes, we want to have some E2E test, which could reproduce same test steps.
What I think right now is using separate function for testing, but if there is a quick way to run other test with one statement which would be great.
test('test1', () => {
})
test('test2', () => {
// run test1 here
})

What I understand from your comment on another answer is: You want to share part of a test just for some specific tests.
To do this you can use the beforeEach and beforeAll functions inside a describe block.
See my example:
describe('some module', () => {
it('should test something awesome', () => {
// My test 1
})
it('should test something awesome', () => {
// My test 2
})
describe('something specific or tests that are related to each other', () => {
beforeEach(() => {
// code that runs for each tests within this describe block
})
it('should test something awesome', () => {
// My test 3
})
it('should test something awesome', () => {
// My test 4
})
})
})

I don't know if I understood your question very well.
What I understood was that you have some steps that we need to write to all tests right?
I think that you can use the beforeEach or beforeAll function to not repeat this code. But is always good that your test to transmit everything that do you need to create the senary.
Tests should work as a document as well!

Related

Why does jest mock for mocking an import doesn't work when jest.mock is called inside a test suite?

I am not able to understand how imports work in unit tests with jest.
I was trying to mock a hook exported from someFile
jest.mock('src/someFile', () => ({
useFetch: () => ({ ... }),
}));
When it's written outside the described block, I am able to run the test as expected.
However, moving the jest mock block inside the describe block or a test block doesn't work.
describe('someHOC', () => {
jest.mock('src/someFile', () => ({
useFetch: () => ({ ... }),
}));
// Followed by tests
});
Can someone suggest to me if we can make it work the same way with some changes, or is it not possible?
Also, is __esModule: true, required in this case, why or why not?

Test Jest and NestJs

I have a service (in Nestjs) and I want test the function exception whit Jest.
My service:
class MyService{
public throwError(ms: string) {
throw new UnprocessableEntityException(ms);
}
}
And I want test it, but I don't know how to do it.
I feel like jest's docs point this out pretty well, but as a quick example, for the above code you'd just need something simple like
describe('MyuService', () => {
describe('throwError', () => {
it('should throw an UnprocessableEntityException', () => {
const myService = new MyService();
expect(
() => myService.throwError('some string')
).toThrow(new UnprocessableEntityException('some string'));
})
})
})
For even more examples, there's a git repo here with a lot of different samples from rxjs to typeorm to graphql, sync and async

spyOn question regarding function that return promise

This is a rather general question about spyOn when writing unit tests with functions that return promises in a Vue component.
The way I write test is the following:
// Basically this function gets data from a service and sets some data in the component.
function getSomething() {
ServiceX.getSomething().then(response =>
this.x = response.x
)
}
the test:
describe('test', () => {
beforeEach() => {
vm = shallowMount(VueComponent)
spyOn(serviceX, 'getSomething).and.returnValue(promsie.resolve(data));
}
it('should set X', () =>{
vm.getSomething()
expect(vm.X).toBe(X);
})
}
The issue is, when I do the test this way, the variable X is not set yet, but if I do the "it" statement async and await for the getSomething() method it works.
I wonder if there is another way to do this.
Because your original method returns a promise, and your spy is also returning a promise (even an already resolved) you should use the then or the async await as you commented in the question.
So, the other way of doing is:
it('should set X', (done) => {
vm.getSomething().then(() => {
expect(vm.X).toBe(X);
done();
});
})
Using the done parameter from jasmine to notify this unit test is asynchronous and will complete when this callback is called.
i know it's a little bit too late and you probably already found a solution, but in case you didn't i think that the solution i will propose will work for you. You can use the combination of fakeAsync and tick to test your asynchronous function, bellow is my solution.
describe('test', () => {
...
it('should set X', fakeAsync(() =>{
vm.getSomething();
tick();
expect(vm.X).toBe(X);
}));
...
}

Mocking BsModalRef for Unit Testing

I am using the BsModalRef for showing modals and sending data using the content property. So we have some like this :
this.followerService.getFollowers(this.bsModalRef.content.channelId).subscribe((followers) => {
this.followerList = followers;
this.followerList.forEach((follower) => {
follower.avatarLink = this.setUserImage(follower.userId);
this.followerEmails.push(follower.email);
});
});
We are setting the channelId in content of bsModalRef (this.bsModalRef.content.channelId). It is working fine. Now i am writing a unit test for this. Problem is i am not able to mock it. I have tried overriding, spy etc but nothing seems to work. I am using the approach mentioned in this link. One alternative is to use TestBed but i am not much aware of its use. Can anyone please help me finding any approach by which this can be achieved ?
I recently had to do something similar and Mocking the method call worked. The tricky part is injecting the BsModalService in both the test suite and the component.
describe('MyFollowerService', () => {
configureTestSuite(() => {
TestBed.configureTestingModule({
imports: [...],
declarations: [...],
providers: [...]
}).compileComponents();
});
// inject the service
beforeEach(() => {
bsModalService = getTestBed().get(BsModalService);
}
it('test', () => {
// Mock the method call
bsModalService.show = (): BsModalRef => {
return {hide: null, content: {channelId: 123}, setClass: null};
};
// Do the test that calls the modal
});
});
As long as you're calling bsModal as follows this approach will work
let bsModalRef = this.modalService.show(MyChannelModalComponent));
Finally, here are some links that have more indepth coverage about setting up the tests with TestBed.
https://chariotsolutions.com/blog/post/testing-angular-2-0-x-services-http-jasmine-karma/
http://angulartestingquickstart.com/
https://angular.io/guide/testing

React Native: Jest mocking Platform

When writing unit tests for a React Native project I want to be able to test different snapshots based on different platforms.
I first tried jest.mock to mock Platform but seems to be async. This approach does work when I have two separate files, but I'd prefer to keep everything in one file if possible.
I tried jest.doMock because of this snippet from the documentation:
When using babel-jest, calls to mock will automatically be hoisted to the top of the code block. Use this method if you want to explicitly avoid this behavior.
https://facebook.github.io/jest/docs/en/jest-object.html#jestdomockmodulename-factory-options
However I'm still seeing undesirable results. When I console.log in the android test I see that Platform.OS is whatever I set the first doMock to be.
I also tried wrapping the mock in a beforeEach in a describe becasue I thought that might help with scoping
http://facebook.github.io/jest/docs/en/setup-teardown.html#scoping
describe('ios test', () => {
it('renders ui correctly', () => {
jest.doMock('Platform', () => {
const Platform = require.requireActual('Platform');
Platform.OS = 'ios';
return Platform;
});
const wrapper = shallow(<SomeComponent />);
const tree = renderer.create(wrapper).toJSON();
expect(tree).toMatchSnapshot();
});
});
describe('android test', () => {
it('renders ui correctly', () => {
jest.doMock('Platform', () => {
const Platform = require.requireActual('Platform');
Platform.OS = 'android';
return Platform;
});
const wrapper = shallow(<SomeComponent />);
const tree = renderer.create(wrapper).toJSON();
expect(tree).toMatchSnapshot();
});
});
Any ideas on how I can change the mock Platform for tests in the same file?
There are a lot of suggestions on how to solve this problem in another question, but none of them worked for me either, given the same requirements you have (tests for different OSs in the same suite file and in one test run).
I eventually worked around it with a somewhat clunky trivial helper function that can be mocked as expected in tests – something like:
export function getOS() {
return Platform.OS;
}
Use it instead of Platform.OS in your code, and then simply mock it in your tests, e.g.
it('does something on Android', () => {
helpers.getOS = jest.fn().mockImplementationOnce(() => 'android');
// ...
}
That did the trick; credit for the idea is due to this guy.