茉莉:我怎么能声明一个循环'其'而不是'期望'用于测试有角度的工厂

jasmine: How can i declare a loop of 'its' instead of a loop of 'expects' for testing an angular factory?

本文关键字:用于 期望 测试 工厂 声明 一个 茉莉 循环 怎么能      更新时间:2023-09-26

这是我要测试的角度工厂:

var myApp = angular.module('myApp', []);
myApp.factory('factoryTest',function(){
    return [
        {number: 1, name: 'one'},
        {number: 2, name: 'two'},
        {number: 3, name: 'three'}
    ];
});

这就是测试它的茉莉花方法:

beforeEach(inject(function (_factoryTest_) {
    factoryTest = _factoryTest_;
}));
it('verifies every item has a number', function(){
    for(var i=0;i < factoryTest.length; i++){
        expect(factoryTest[i].number).toEqual(jasmine.any(Number));
    }
});

上面的测试是有效的,但是在失败的情况下,你不知道哪一项是失败的。

为了使错误有意义,必须将其重构为"its"的循环:

beforeEach(inject(function (_factoryTest_) {
    factoryTest = _factoryTest_;
}));
for(var i=0;i < factoryTest.length; i++){
    it('verifies ' + factoryTest[i].name + ' has a number', function(){
        expect(factoryTest[i].number).toEqual(jasmine.any(Number));
    });
}

然而,这失败了,因为factoryTest没有注入到描述上下文中。我如何注入棱角分明的工厂使其工作?

我做了一把小提琴:http://jsfiddle.net/rodhom/woq9fhg9/

我第一次发现循环"its"的想法,在这里:http://tosbourn.com/using-loops-in-jasmine/

请参阅我之前的评论,因为我认为您遇到了XY问题

jasmine分阶段评估测试定义。在评估describe的点处,分配factoryTestbeforeEach尚未被评估<我目前找不到确切的订单是什么>

要让错误消息指示期望在哪个对象中失败,请创建一个自定义匹配器,并在it阶段迭代期望。

定义如下自定义匹配器:

beforeEach(function () {
    var customMatchers = {
        toHaveNumericProperty: function (property) {
            var instance = this.actual;
            var description = instance.name || instance.toString();
            var isNumeric = typeof instance[property] === 'number';
            this.message = function() {
                return isNumeric ? '' : 'Expected ''' + description + '.' + property + ''' to be numeric';
            };
            return isNumeric;
        }
    };
    this.addMatchers(customMatchers);
});

然后在测试中使用它,如下所示:

it('verifies each object has a number',
function () {
    for (var i = 0; i < factoryTest.length; i++) {
        expect(factoryTest[i]).toHaveNumericProperty('number');
    }
})

我已经用叉子叉了你的小提琴来使用这个解决方案

问题的解决方案是创建一个包含factoryTest变量的闭包。

beforeEach(inject(function (_factoryTest_) {
    factoryTest = _factoryTest_;
}));
for(var i=0;i < factoryTest.length; i++){
    it('verifies ' + factoryTest[i].name + ' has a number', 
        createFactoryTestClosure(factoryTest[i]));
}
function createFactoryTestClosure(factoryElement) {
    return function() {
        expect(factoryElement.number.toEqual(jasmine.any(Number));
    };
}