I'm new to qUnit with UI5.
I want to test one function formatter.js
formatDate: function(sTimeStamp) {
if (sTimeStamp) {
var iTimeStamp = Number(sTimeStamp.match(/\d/g).join("")),
oDateTimeFormat = DateFormat.getDateTimeInstance();
return oDateTimeFormat.format(new Date(iTimeStamp));
}
return sTimeStamp;
},
Unit test for it:
function formatDateTestCase(assert, sValue, fExpectedNumber) {
var fDate = formatter.formatDate(sValue);
assert.strictEqual(fDate, fExpectedNumber, "Format Date was correct");
}
QUnit.test("Should return valid date", function (assert) {
formatDateTestCase.call(this, assert, "/Date(1510026665790)/", "Nov 7, 2017, 11:51:05 AM");
});
Obviously, this test case will fail when I change language setting. How to improve it?
I think the main problem here is that formatDate
is a function with side effects. Should I improve this function itself? By adding locale in formatDate
?
Or should I use DateFormat
in my test case? Which will make my test meaningless.
I think you should mock the calls to DateFormat
here to be able to independently test your code.
Unit Test Considerations
Strictly speaking the point of a Unit Test is to test your - and only your - Unit. You should not test any dependent API. One could argue about that in general but I would definitely NOT recommend to test SAPUI5 API.
One the other hand I would strongly recommend to test the if
statement and the Regex part with invalid params (e.g. undefined
) and invalid strings. This will ensure your formatter to always work and to return sth. meaningful if it is an empty string.
Sinon.JS: Mocks, Stubs and Spys
You should stub DateFormat.getDateTimeInstance()
in your specific test so that the method returns a predictable value (e.g. think of I18N in DateFormat
that would give you different test results in different languages).
To do that SAPUI5 already ships with Sinon.JS (be aware of the version included: SAPUI5 1.44 -> Sinon.JS 1.14). Here is a basic example:
sap.ui.define([
"my/module/formatter",
"sap/ui/core/format/DateFormat",
"sap/ui/thirdparty/sinon",
"sap/ui/thirdparty/sinon-qunit"
], function (formatter, DateFormat) {
QUnit.test("Should return valid date", function (assert) {
// stub the method
sinon.stub(DateFormat, "getDateTimeInstance");
// ensure a predictable outcome
DateFormat.getDateTimeInstance.returns({
format: function(oDate) {
return oDate.getTime();
}
});
var fDate = formatter.formatDate("/Date(1510026665790)/");
assert.strictEqual(fDate, "1510026665790", "Format Date was correct");
// Optional: test if the stubbed function was called
assert.ok(DateFormat.getDateTimeInstance.calledOnce);
// don't forget to restore the stub so that it does not interfere with other tests
DateFormat.getDateTimeInstance.restore();
});
});
By stubbing DateFormat.getDateTimeInstance
you stop testing core API and it's outcomes and you can focus on what matters most: YOUR code.
BR Chris