I am trying to write unit tests for a mobile app that has been developed in Appcelerator titanium. I am trying to unit test it with TiUnit and Jasmine.
One of my methods uses String.format()
. How do I unit test that method since String.format()
is not defined in Javascript?
function MyMethod(_flag, _myProperty, _propertyValue) {
if(_flag) {
_myProperty = String.format('The value :', _propertyValue);
}
}
Is it possible to mock this? Or can I add format() to the prototype of jasmine's String so that whenever it encounters format() in .js to be tested, it executes the format() which I will define in the test suite?
A way to get around this problem is to make this a pure function.
Take this small change as an example:
function MyMethod(_flag, _myProperty, _propertyValue, formatFunction) {
if(_flag) {
_myProperty = formatFunction('The value :', _propertyValue);
}
}
Now MyMethod
does not have a dependency on anything external to the function. This allows you to use whatever string formatter you want, and in your case a mocked one.
In your test, you now have the ability to do something like this:
it('should format the string', () => {
const mockFormatter = () => {/*do the mock operation of your choosing here*/}
const formattedString = MyMethod(yourFlag, yourProperty, yourPropertyValue, mockFormatter)
assert(formattedString, expectedOutput)
})
What this allows is for you to not have to manipulate the global String object/prototypes, which can have implications elsewhere. Instead, you create a function that is agnostic to the formatter and are able to easily mock it.
Lastly, now that I have hopefully helped provide a path forward on your original question, I'm curious why you are after mocking the formatter? This seems like something you would always want to validate, and would have no harm in doing so. To me, and this can lead to very in depth and often pedantic discussions on testing, this already suffices as a unit test. It is not "pure", but as far as side-effects go, there are none and you are testing some basic expectations around data manipulation without.
I think mocking String.format()
introduces unnecessary complexity to the test without any real gain in code-confidence.
**Edit: I assumed String.format()
was a JS function I had not heard of, but that does not appear to be the case.
To achieve what you are after, and avoid the need to mock entirely, I think you should use string interpolation via string literals, or concatenation.
See here:
function MyMethod(_flag, _myProperty, _propertyValue) {
if(_flag) {
_myProperty = `The value : ${_propertyValue}`; // option 1 uses interpolation
// _myProperty = 'The value : ' + _propertyValue; // option 2 uses concatenation
}
}