I have a service in my angular app that looks something like this:
angular.module('BracketService', []).factory('BracketService', [function() {
function compareByWeight(a, b) {
return a.weight - b.weight;
}
function filterWeightGroup(competitors, lowWeight, highWeight) {
//filter stuff
}
function createBracketsByWeightGroup(weightGroup) {
//create some brackets
}
//set some base line values
var SUPER_HEAVY_WEIGHT = 500;
var SUPER_LIGHT_WEIGHT = 20;
return {
//create brackets from a list of competitors
returnBrackets: function(competitors) {
var brackets = {};
//get super light weights
brackets.superLightWeights = createBracketsByWeightGroup(
filterWeightGroup(competitors, 0, SUPER_LIGHT_WEIGHT)
.sort(compareByWeight)
);
brackets.superHeavyWeights = createBracketsByWeightGroup(
filterWeightGroup(competitors, SUPER_HEAVY_WEIGHT, Infinity)
.sort(compareByWeight)
);
brackets.middleWeights = createBracketsByWeightGroup(
filterWeightGroup(competitors, SUPER_LIGHT_WEIGHT, SUPER_HEAVY_WEIGHT)
.sort(compareByWeight)
);
return brackets;
}
};
}]);
I would like to unit test not just the functions / properties that are exposed in the return statement, but also the functions that are outside of the return statement.
My test is currently set up something like this:
describe('BracketService', function() {
beforeEach(module('bracketManager'));
it('calling return brackets with no competitors will return 3 empty weight classes', inject(function(BracketService) {
var mockCompetitors = [];
var mockBracketResult = {superHeavyWeights: [[]], superLightWeights: [[]], middleWeights: [[]]};
expect(BracketService.returnBrackets(mockCompetitors)).toEqual(mockBracketResult);
}));
});
But how do I test the compare, filter and createBrackets functions that are not exposed by the return statement?
Thanks!
Strictly speaking, you should not be writing unit tests that directly test private methods. What you should be testing is the public contract that the class has with other objects; you should never directly test an object's internals.
Create an Angular project with jasmine and karma By doing this, the jasmine and karma configuration is resolved for us. Install and create a new project with angular-cli: Install npm -g @angular/cli. Ng new angular-unit-testing angular unit-testing.
There is no way to test those functions. Their scope is the function that comprises your BracketService factory and they are invisible anyplace else. If you want to test them, then you have to expose them somehow.
You can move them into their own service (which seems like overkill) or you can black box test your BracketService service with enough data combinations to make sure the internal functions are working. That's probably the most sensible approach.
If you don't want to put them in a separate service, but still feel the need to test those internal functions, just return them from the factory along with returnBrackets.
I might do this when I have a number of helper functions that are straight forward to test individually, but open up a combinatorial Pandora's box to black box test. I usually preface such functions with an "_" to show they are helper functions and are only exposed for testing.
return {
//create brackets from a list of competitors
returnBrackets: function(competitors) {...},
_filterWeightGroup: filterWeightGroup,
_createBracketsByWeightGroup: createBracketsByWeightGroup
};
You will not be able to call those functions without exposing them somehow. But, IMHO, private methods should not have a unit test perse, but be tested at the time the public method that calls them is tested. What you should do is mock the objects that your private function will receive and you will be able to perform expectations on them.
The only way to test them in your current setup is to test the returned function since they're currently local to the scope inside the BracketService
. If you want them to be individually testable, you'll need to expose them in the return statement as properties of BracketService
.
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