如何使用 Karma 和 Jasmine 在 angular 服务中测试 'private' 函数
How to test 'private' functions in an angular service with Karma and Jasmine
我的 angular 应用程序中有一项服务看起来像这样:
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;
}
};
}]);
我不仅要对 return 语句中公开的函数/属性进行单元测试,还要对 return 语句之外的函数进行单元测试。
我的测试目前设置如下:
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);
}));
});
但是如何测试 return 语句未公开的 compare、filter 和 createBrackets 函数?
谢谢!
无法测试这些功能。它们的范围是构成您的 BracketService 工厂的功能,它们在其他任何地方都是不可见的。如果你想测试它们,那么你必须以某种方式暴露它们。
您可以将它们移到它们自己的服务中(这看起来有点矫枉过正),或者您可以使用足够的数据组合对您的 BracketService 服务进行黑盒测试,以确保内部功能正常工作。这可能是最明智的做法。
如果您不想将它们放在单独的服务中,但仍然觉得有必要测试这些内部功能,只需 return 将它们与 return 支架一起出厂即可。
当我有许多可以直接单独测试的辅助函数时,我可能会这样做,但打开了一个组合潘多拉魔盒到黑盒测试。我通常在此类函数前加上“_”,以表明它们是辅助函数,仅供测试使用。
return {
//create brackets from a list of competitors
returnBrackets: function(competitors) {...},
_filterWeightGroup: filterWeightGroup,
_createBracketsByWeightGroup: createBracketsByWeightGroup
};
如果不以某种方式公开这些函数,您将无法调用它们。但是,恕我直言,私有方法本身不应该有单元测试,而是在测试调用它们的 public 方法时进行测试。你应该做的是模拟你的私有函数将接收的对象,你将能够对它们执行期望。
在当前设置中测试它们的唯一方法是测试 returned 函数,因为它们当前在 BracketService
范围内。如果您希望它们可以单独测试,则需要在 return 语句中将它们公开为 BracketService
.
的属性
我的 angular 应用程序中有一项服务看起来像这样:
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;
}
};
}]);
我不仅要对 return 语句中公开的函数/属性进行单元测试,还要对 return 语句之外的函数进行单元测试。
我的测试目前设置如下:
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);
}));
});
但是如何测试 return 语句未公开的 compare、filter 和 createBrackets 函数?
谢谢!
无法测试这些功能。它们的范围是构成您的 BracketService 工厂的功能,它们在其他任何地方都是不可见的。如果你想测试它们,那么你必须以某种方式暴露它们。
您可以将它们移到它们自己的服务中(这看起来有点矫枉过正),或者您可以使用足够的数据组合对您的 BracketService 服务进行黑盒测试,以确保内部功能正常工作。这可能是最明智的做法。
如果您不想将它们放在单独的服务中,但仍然觉得有必要测试这些内部功能,只需 return 将它们与 return 支架一起出厂即可。
当我有许多可以直接单独测试的辅助函数时,我可能会这样做,但打开了一个组合潘多拉魔盒到黑盒测试。我通常在此类函数前加上“_”,以表明它们是辅助函数,仅供测试使用。
return {
//create brackets from a list of competitors
returnBrackets: function(competitors) {...},
_filterWeightGroup: filterWeightGroup,
_createBracketsByWeightGroup: createBracketsByWeightGroup
};
如果不以某种方式公开这些函数,您将无法调用它们。但是,恕我直言,私有方法本身不应该有单元测试,而是在测试调用它们的 public 方法时进行测试。你应该做的是模拟你的私有函数将接收的对象,你将能够对它们执行期望。
在当前设置中测试它们的唯一方法是测试 returned 函数,因为它们当前在 BracketService
范围内。如果您希望它们可以单独测试,则需要在 return 语句中将它们公开为 BracketService
.