Automated Unit Tests using QUnit JS in an Oracle JET project

Daniel Curtis
Oracle Developers
Published in
5 min readJan 24, 2018

Update July 2019 — I would no longer recommend using QUnit for testing JET applications. Jasmine or Jest are both better alternatives. You can find out more information about how to setup and use Jasmine within an Oracle JET application in Chapter 13 of Practical Oracle JET.

[1] ToolsQA

Why is unit testing always a sore subject? It shouldn't be, but it takes a multitude of things to come together to ensure a team of developers write good automated unit tests for their work. One of these is deciding on a unit test framework to use (it’s a bit of a maze out there), and making it really easy for developers to write their tests.

The last thing you want to worry about when you are facing tight deadlines is having to learn a new testing framework, on top of the pile of other tasks you likely have on your backlog. Hopefully, the next few minutes will give you a head start in getting a skeleton unit test framework working in your project, ready for those important automated tests to be written.

This article demonstrates QUnit within an Oracle JET project, QUnit is the chosen framework as there is plenty of support, and it is one of the reccomended frameworks to use for JET.

The examples below were written in Oracle JET 4.1

Create your folder structure

First of all, create a folder in your /src/ folder named ‘tests’. In order for the watch task to monitor for changes on your tests (supported in JET v4+), you must have all your unit tests within the /tests/ directory.

You will also want to create src/tests/modules and src/tests/data folders too, this will hold all your modulated QUnit test files and mock JSON payloads.

Note: It is possible to change the directory name for your tests (as it is for all your src folder paths) - in oraclejetconfig.json.

You will notice that if you now do an ojet build, JET acknowledges that you now have unit tests in your app, and will automatically start bringing the QUnit library over into your web/libs folder — sweet!

Import mockjax

jquery-mockjax is a really useful plugin that provides a handle onto AJAX responses, so that you can manipulate the response and return mock data to your tests.

To install mockjax run the following:

npm install jquery-mockjax --save

Once this has completed, you need to copy the library files over to your application’s staging directory. Make the following change to your /scripts/oraclejet-build.js file:

copyCustomLibsToStaging: {
fileList: [
{
cwd:'node_modules/jquery-mockjax/dist',
src: ['jquery.mockjax.js'],
dest: 'web/js/libs/jquery-mockjax'
}
]
},

Setup your entry point

You must create two files for your entry point for your tests. One is your index.html, where you will initiate your tests, and see the results. The second is your main.js file.

Create a new main.js file in your src/tests/ directory, this will be the entry point for your unit tests to run, and will load all the require.js dependencies and test modules.

The main.js will be similar to the one that you use for your JET application, with a couple of changes. So as a starting point you can copy over the contents from src/js/main.js, and make the following changes:

  1. Your baseUrl value will be slightly different. You’ll have to change this to move up one directory, so it would be ../js instead of just js.
  2. Ensure you have added mockjax and your viewModel dependancies
  3. The require block will be different, as it is used to load all your test modules and also initiate QUnit. You may want to add extra functionality into this block at a later stage.

require path config

requirejs.config(
{
baseUrl: '../js',
// Path mappings for the logical module names
paths:
{
'knockout': 'libs/knockout/knockout-3.4.0.debug',
'jquery': 'libs/jquery/jquery-3.1.1',
'jqueryui-amd': 'libs/jquery/jqueryui-amd-1.12.0',
'promise': 'libs/es6-promise/es6-promise',
'hammerjs': 'libs/hammer/hammer-2.0.8',
'ojdnd': 'libs/dnd-polyfill/dnd-polyfill-1.0.0',
'ojs': 'libs/oj/v4.0.0/debug',
'ojL10n': 'libs/oj/v4.0.0/ojL10n',
'ojtranslations': 'libs/oj/v4.0.0/resources',
'text': 'libs/require/text',
'signals': 'libs/js-signals/signals',
'customElements': 'libs/webcomponents/custom-elements.min',
'proj4': 'libs/proj4js/dist/proj4-src',
'css': 'libs/require-css/css',
'mockjax': 'libs/jquery-mockjax',
// View Models
'dashboardViewModel': 'viewModels/dashboard.js'
}, shim:
{
'jquery':
{
exports: ['jQuery', '$']
}
}
});

require block

var testModules = [   // General Imports   'jquery',
'knockout',
'appController',
'mockjax',
// Test Suites - add all your test modules here

'modules/dashboardTests.js'
];
require(testModules, function ($, ko, app) {
ko.applyBindings(app, document.getElementById('globalBody'));
QUnit.start();
});

Your index file will look like this, and will be stored within src/tests/index.html

<!DOCTYPE html>   <html>      <head>         <title>My first Oracle JET QUnit Tests</title>
<link rel="stylesheet" href="../js/libs/qunit/qunit.css">
</head> <body> <div id="qunit"></div>
<div id="qunit-fixture"></div>
<script src="../js/libs/qunit/qunit.js"></script>
<script data-main="main" src="../js/libs/require/require.js">
</script>
<div id="globalBody"></div>
<script type="text/javascript" charset="utf-8">
QUnit.config.autostart = false;
</script>
</body>
</html>

Create your dashboardTests.js file

Now that you have your framework in place, you can start writing your tests! I wont go into detail on how QUnit tests work, as this is all documented quite extensively online, and on the QUnit website.

I will show a quick example of how to run a QUnit test in an Oracle JET application.

Example of dashboard viewModel

Imagine I have an external service that returns a date. I then do a check on this date to see if matches with todays date. The result is stored within an observable.

self.dateBoolean = ko.observable();self.runService = function() {    // AJAX call and date check logic    self.dateBoolean(result);};

Example dashboardTests.js

Now I want to write a test, to ensure my date logic is correct. We can use mockjax to modify the response payload, so I have full control over what date the service call returns.

My mock response will be stored in data/dashboard.json, and assigned to the mockjax proxy attribute.

require(['dashboardViewModel'], function (viewModel) {   QUnit.module("Dashboard tests", {});   var vm = new viewModel();    function init(){
$.mockjax({
url: 'http://myservicelocation',
type: 'GET',
responseTime: 0,
contentType: 'text/json',
proxy: 'data/dashboard.json'
});
}
QUnit.test("Sample test", function (assert){
init();
vm.runService();
var done = assert.async();
setTimeout(function () {
assert.equal(vm.dateBoolean(), true, "Dates matched");
done();
}, 100);
});
});

For more information on how to use QUnit, please visit the website, which contains a lot of useful examples:

— DC

[1] Image Credit — http://toolsqa.com/software-testing/software-testing-tutorial/

--

--

Daniel Curtis
Oracle Developers

Lead Front End Developer at Griffiths Waite - JET, React, ADF & WCS. Author of Practical Oracle JET (http://www.practicaloraclejet.co.uk) & Oracle Ace