I have a function, which has another function in it. And in the second function we are making an API call. So how can I write a unit test for this scenario? I don't want to make an actual API call, I want to mock it.
const getData = async (data) => {
const res = await got.post(url,{
json: {data}
});
const data = res.data;
return data;
}
function firstFunction(args) {
// perform some operation with args and it's stored in variable output.
let output = args;
let oo = getData(args);
console.log(oo)
}
CodePudding user response:
When running unit test you don't have to call real API calls. You have to encapsulate your component and provide any external information.
With jest you can mock the http call and return what you want. And also you can check if the mock has been called.
import { got } from "anyplace/got";
import { firstFunction } from "anyplace2";
jest.mock("anyplace/got", () => ({
// here you provide a mock to any file that imports got to make http calls
got: {
// "mockResolvedValue" tells jest to return a promise resolved
// with the value provided inside. In this case {data: 'what you
// want here'}
post: jest.fn().mockResolvedValue({data: 'what you want here'});
}
}));
describe('My test', () => {
beforeEach(() => {
// This will clear all calls to your mocks. So for every test you will
// have your mocks reset to zero calls
jest.clearAllMocks();
});
it('Should call the API call successfully', () => {
// execute the real method
firstFunction({arg: 1});
// check that the API has been called 1 time
expect(got.post).toHaveBeenCalledTimes(1);
expect(got.post).toHaveBeenCalledwith("myurlhere", {data: {arg: 1}});
})
});
CodePudding user response:
You can simulate it with setTimeout, I further provided a mock response so after 1000ms it will send a Promise with this user array
const getData = () => {
return new Promise((resolve, reject) => {
setTimeout(resolve({
users: [
{ name: "Michael" },
{ name: "Sarah" },
{ name: "Bill" },
]
}), 1000)
})
}
CodePudding user response:
This is what I do when there is a function making use of console.log
and I want to suppress (or monitor) console output:
Sample function
function hasData(data) {
console.log(data);
return !!data;
}
Test suite
describe('Testing hasData', () => {
it('should return true', () => {
// save original function
const __log = console.log;
let hasConsoleLog = false;
// override function
console.log = () => hasConsoleLog = true;
expect( hasData({ foo: true }) ).toBe(true);
expect( hasConsoleLog ).toBe(true);
// restore original function
console.log = __log;
});
});
If you can override got.post
to something like:
got.post = async (url, data) => {
return res; // implement your mock-up response, here
};
then you can inject a testable API.