0

我正在对我的 ember 应用程序进行集成测试,但我的一个测试失败了,因为我的测试运行后承诺解决了。我的承诺包含一个动画事件(bs 崩溃)。这是我要测试的代码的一部分:

//in my component 
/**
 * Closes the component DOM with collapse animation
 *
 * @method 'animateClose'
 * @return {Ember.RSVP.Promise} promise that gets resolved once the collapse animation is complete
 */
animateClose() {
    let element = Ember.$(this.get('element'));
    return new Ember.RSVP.Promise(function(resolve) {
        element.on('hidden.bs.collapse', function() {
            resolve();//never gets here!!!
        });
        element.collapse('hide');
    });
},

actions: {

    /**
     * Invokes close action.
     *
     * @action 'close'
     * */
    close() {
        let defer = Ember.RSVP.defer();

        defer.promise.then(function() {
            return this.animateClose().then(function() {
                this.sendAction("close");
            }.bind(this));
        }.bind(this));

        this.sendAction("confirmClose", defer);
    }
}

正如你所看到的,我将一个 defer 对象传递给控制器​​,控制器将根据一些标准来解决它,如果 defer 对象得到解决,它会在组件上执行折叠动画并关闭它。我的测试代码如下所示:

test("should save and close", function(assert) {

        click(".save-close-btn");//this invokes the close action in component
        //wait();
        andThen(function() {
            //assert something
        });

});

当我调试它时,我可以看到我的断言首先被击中,然后从 animateClose 返回的承诺解决了导致我的测试失败。我该如何解决这个问题?谢谢。

更新:事实证明我的组件由于某种原因没有完全崩溃,因此“animateClose”中的解析没有被触发。不知道为什么折叠事件没有完成并且 dom 处于“折叠”状态

临时解决方案:现在我放弃了引导折叠并使用 jquery 幻灯片动画代替,我的测试工作正常。测试环境中一定发生了一些与引导折叠动画/事件相混淆的事情。

4

1 回答 1

1

最常见的(反)模式是检查组件是否已被销毁。

close() {
    let defer = Ember.RSVP.defer();

    defer.promise.then(function() {
        return this.animateClose().then(function() {
            if (!this.get('isDestroyed')) {
                this.sendAction("close");
            }
        }.bind(this));
    }.bind(this));

    this.sendAction("confirmClose", defer);
}

这是完全可以接受的,并且仅用于通过您的测试。请注意,如果您的组件被销毁,动画实际上不会停止。

然而,最近 Ember 核心团队的 Alex Matchneer 开创了一种更好的解决方案,其中包括可取消的承诺。他发布了一个插件,其结果是:ember-concurrency。有关更多信息,请参阅文档

于 2016-02-17T19:04:27.313 回答