首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >有承诺的角服务单元测试失败

有承诺的角服务单元测试失败
EN

Stack Overflow用户
提问于 2015-10-12 13:46:02
回答 1查看 116关注 0票数 1

JSFiddle显示了这个问题:

http://jsfiddle.net/ggvfwoeL/3/

我有一个有角度的应用程序,其中包含一个用于生成威胁的服务。威胁生成使用鼻涕规则引擎完成。该服务公开了一个返回承诺的函数generateForElement。函数如下所示(有关详细信息,请参阅JSFiddle ):

代码语言:javascript
复制
var Element = function (element) { this.type = element.attributes.type; }
var Threats = function () { this.collection = []; }    

    function generateForElement(element) {
           var threats = new Threats();
           var el = new Element(element);
           flow.getSession(threats, el).match();
           return $q.when(threats.collection);
    }

规则引擎被设置为当您使用一个元素(即一个generateForElement类型)调用tm.Process时,它会生成两个威胁。下面是定义规则的代码(显然,为了使问题更加清晰,这大大简化了):

代码语言:javascript
复制
function initialiseFlow() {
        return nools.flow('Element threat generation', function (flow) {

            flow.rule('Spoofing Threat Rule', [
                [Element, 'el', 'el.type == "tm.Process"'],
                [Threats, 'threats']
            ], function (facts) {
                facts.threats.collection.push('Spoofing');
            });

            flow.rule('Tampering Threat Rule', [
                [Element, 'el', 'el.type == "tm.Process"'],
                [Threats, 'threats']
            ], function (facts) {
                facts.threats.collection.push('Tampering');
            });
        });
    }

当我在我的应用程序中手动测试这一点时,我看到了正在生成的2种威胁。但是我的单元测试在这条线上失败了

代码语言:javascript
复制
expect(threats.length).toEqual(2);

有错误

代码语言:javascript
复制
Error: Expected 1 to equal 2.

因此,似乎只有一个威胁正在产生。单元测试定义如下:

代码语言:javascript
复制
describe('threatengine service', function () {

    var threatengine;
    var $rootScope;

    beforeEach(function () {

        angular.mock.module('app')

        angular.mock.inject(function (_$rootScope_, _threatengine_) {
            threatengine = _threatengine_;
            $rootScope = _$rootScope_;
        });

        $rootScope.$apply();
    });

    describe('threat generation tests', function () {

        it('process should generate two threats', function () {

            var element = { attributes: { type: 'tm.Process' }};
            var threats;
            threatengine.generateForElement(element).then(function (data) {
                threats = data;
            });
            expect(threats).toBeUndefined();
            $rootScope.$apply();
            expect(threats).toBeDefined();
            expect(threats.length).toEqual(2);
        });
    });
});

很明显我做错了什么。正如我所说的,当我运行完整的应用程序时,我肯定会收到两个威胁,让我认为错误要么是单元测试的错误,要么是我在服务中处理承诺的方式,但我就是看不见。

为什么我的单元测试失败?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-10-12 14:43:36

第一个问题是flow.getSession(threats, el).match();调用,它在代码中被同步调用,但最初它似乎是异步的(我不熟悉nools,而是这是文件)。因此,即使将console.log放在两个规则的处理程序中,您也会看到,处理规则的时间要比下面的同步代码晚得多。它的解决方案是使用一个承诺,.match()返回该承诺:

代码语言:javascript
复制
function generateForElement(element) {
    var threats = new Threats();
    var el = new Element(element);
    // handle async code via promises and resolve it with custom collection
    return flow.getSession(threats, el).match().then(function () {
      return threats.collection;
    });
}

另一个问题是在测试文件中。在那里,您也有异步代码,但您处理它像同步代码一样。见茉莉花文档中的异步支持。基本上,如果您的测试是异步的,您必须告诉Jasmine,并在测试完成时通知它。

代码语言:javascript
复制
it('process should generate two threats', function (done) {
    // telling Jasmine that code is async ----------^^^

    var element = { attributes: { type: 'tm.Process' }};

    // this call is async
    threatengine.generateForElement(element).then(function (threats) {
        expect(threats).toBeUndefined();
        expect(threats).toBeDefined();
        expect(threats.length).toEqual(2);

        done(); // telling Jasmine that code has completed
    });

    // is required to start promises cycle if any
    $rootScope.$apply();
});

这是一个工作的JSFiddle

更新:

以下是Jasmin1.3的规范,它将另一个API用于异步流:

代码语言:javascript
复制
it('process should generate two threats', function (done) {

    var element = { attributes: { type: 'tm.Process' }};
    var threats;

    runs(function () {
        threatengine.generateForElement(element).then(function (data) {
            threats = data;
        });
        $rootScope.$apply();
        });

        waitsFor(function () {
            return typeof threats !== 'undefined';
    });

    runs(function () {
        expect(threats).not.toBeUndefined();
        expect(threats).toBeDefined();
        expect(threats.length).toEqual(20);
    });

});
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33082806

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档