Using jest how can I test a function that makes an ajax request in my jQuery app and mock its response? My app is not compiled in nodejs and runs straight in a browser. The example on the jest site https://github.com/facebook/jest/tree/master/examples/jquery assumes ajax function is a separate module and the whole app gets compiled with something like webpack. Here is my app:
(function(root) {
"use strict";
// if environment is node then import jquery.
var $ = (typeof module === "object" && module.exports) ? require('jquery') : jQuery;
function displayUser() {
var fetchCurrentUser = function (url) {
var xhr = $.get(url);
$.when(xhr)
.done(function(data) {
greet(data);
})
.fail(function(jqXHR, textStatus, errorThrown) {
console.log(errorThrown);
});
};
var greet = function(data) {
$('#greet').text('Hello ' + data.name);
}
fetchCurrentUser('/my/api');
return {
fetchCurrentUser: fetchCurrentUser,
greet: greet
};
}
// Added this conditional so I can test in jest
if (typeof module === "object" && module.exports) {
// Node
module.exports = displayUser();
} else {
// Browser (root is window)
root.displayUser = displayUser();
}
})(this);
Mock $.ajax by using jest.fn().
$.ajax = jest.fn().mockImplementation(() => {
const fakeResponse = {
id: 1,
name: "All",
value: "Dummy Data"
};
return Promise.resolve(fakeResponse);
});
create a __mocks__/jquery.js
in your project root to mock the jquery node_module. You can invoke functions in your mock jquery. Here's a simple code snippet:
const $ = {
ajax(xhr) { return this },
done(fn) {
if (fn) fn();
return this;
},
fail(fn) {
if (fn) fn();
return this;
}
};
export default $;
And add some expect
in your fn
to test your real logic.
The easiest setup that I have found to test files without using modules and webpack is to manually create the scripts and to add them to window.document
. You can reference relative paths directly inside the test file using the fs
and path
modules. Once you have everything working you can follow ycavatars answer in order to mock the ajax calls.
Here is a simple snippet testing basic jQuery functionality, you can then add new scripts to test the functions in your own file:
const fs = require('fs');
const path = require('path');
const jQueryFile = fs.readFileSync(path.resolve(__dirname, '../relative/path/to/jquery.js'), { encoding: 'utf-8' });
const srcFile = fs.readFileSync(path.resolve(__dirname, '../relative/path/to/yourScript.js'), { encoding: 'utf-8' });
describe('yourScript.js', () => {
beforeAll(() => {
// load the scripts
const scriptEl = window.document.createElement('script');
scriptEl.textContent = jQueryFile; // add jQuery file
window.document.body.appendChild(scriptEl);
const scriptEl2 = window.document.createElement('script');
scriptEl2.textContent = srcFile; // add your src file
window.document.body.appendChild(scriptEl2);
});
describe('jQuery behaviour', () => {
test('creates and find elements', () => {
const $form = $('<form><input type="text" name="query" class="ff_search_input col-xs-11" autocomplete="off" placeholder="Che cosa stai cercando?"></form>');
const $input = $form.find('input');
expect($input.length).toBeGreaterThanOrEqual(1);
});
});
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With