gpt4 book ai didi

javascript - Jasmine 2.0 中的异步工作流测试

转载 作者:行者123 更新时间:2023-11-29 22:00:28 25 4
gpt4 key购买 nike

我有一个 AngularJS 应用程序,我需要在其中测试工作流并确保在广播事件后设置正确的值。

在 1.3 中我会这样做:

it('should have the correct match workflow', function() {
// matchMaking event
runs(function() {
scope.$broadcast('matchMaking', gameId);
});

waitsFor(function() {
return (scope.match && scope.match.game);
}, 'A game should be defined', 3000);

runs(function() {
expect(scope.match.game).toBeDefined();
});

// matchCreate event
runs(function() {
scope.$broadcast('matchCreate', gameId, {}, {});
});

waitsFor(function() {
return scope.match.status === 'CREATED';
}, 'Match status should be \'CREATED\'', 3000);

runs(function() {
expect(scope.match.id).toBeDefined();
expect(scope.match.player).toBeDefined();
expect(scope.match.opponent).toBeDefined();
});

// matchPrepare event
runs(function() {
scope.$broadcast('matchPrepare');
});

waitsFor(function() {
return scope.match.status === 'PREPARED';
}, 'Match status should be \'PREPARED\'', 3000);

runs(function() {
expect(scope.match.id).toBeDefined();
});

// ... continues
});

在 Jasmine 2.0 中,测试工作流的唯一解决方案似乎是将 setTimeout 函数链接在一起(所有期望必须在同一规范内才能使用相同的范围):

beforeEach(inject(function($rootScope, $compile) {
jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;
scope = $rootScope;
element = angular.element('<pg-match-making></pg-match-making>');
$compile(element)($rootScope);
$rootScope.$digest();
}));

it('should have the correct match workflow', function(done) {
var timeoutTick = 100;
scope.$broadcast('matchMaking', gameId);
setTimeout(function(){
expect(scope.match.game).toBeDefined();

scope.$broadcast('matchCreate', gameId, {}, {});
setTimeout(function(){
expect(scope.match.status).toEqual('CREATED');
expect(scope.match.id).toBeDefined();
expect(scope.match.player).toBeDefined();
expect(scope.match.opponent).toBeDefined();

scope.$broadcast('matchPrepare');
setTimeout(function(){
expect(scope.match.status).toEqual('PREPARED');
expect(scope.match.id).toBeDefined();

// ... call done() on the last setTimeout()
}, timeoutTick);
}, timeoutTick);
}, 6000);
});

我最终得到了一堆 7 个 setTimeout,这使得源代码更难阅读并且测试运行起来非常慢。

难道没有更好的方法来使用 Jasmine 2.0 测试工作流吗?

最佳答案

我有解决你问题的方法。我构建了一个与 Jasmine 2.x 配合良好的小型简单异步测试框架,但它使用 jQuery Deferred 对象来安排延续。

function asyncWait(delay) {
return new $.Deferred(function () {
var _self = this;
setTimeout(function () {
_self.resolve();
}, delay || 0);
}).promise();
}

var Async = function(init) {
var d = new $.Deferred(init);
this.promise = d.promise();
d.resolve();
};

Async.prototype.continueWith = function (continuation, delay) {
var _self = this;
_self.promise.then(function () {
_self.promise = asyncWait(delay).then(continuation);
});
return _self;
};

Async.prototype.waitsFor = function (condition, timeout, pollInterval) {
pollInterval = pollInterval || 10;
timeout = timeout || 5000;
var _self = this,
wait_d = new $.Deferred(),
t = 0,
ln = function () {
if (condition()) {
wait_d.resolve();
return;
}
if (t >= timeout) {
wait_d.reject();
throw "timeout was reached during waitsFor";
}
t += pollInterval;
setTimeout(ln, pollInterval);
};
_self.promise.then(ln);
_self.promise = wait_d.promise();
return _self;
};

要使用此代码,请连接 Jasmine 测试并使用 Async 类的新实例,

    it("some async test workflow I want to run", function (done) {
new Async(function () {
//wire up the first async call here
var timeoutTick = 100;
scope.$broadcast('matchMaking', gameId);
}).continueWith(function () {
expect(scope.match.game).toBeDefined();
scope.$broadcast('matchCreate', gameId, {}, {})
}, 6000).continueWith(function () {
//more stuff here
}).waitsFor(function () {
// a latch function with timeout - maybe wait for DOM update or something
return $(".my-statefull-element").val() === "updated";
}, 1000).continueWith(done); //finish by waiting for done to be called
});

这段代码不是 100% 的万无一失,但它对我有用。如果您有任何问题,请告诉我。

关于javascript - Jasmine 2.0 中的异步工作流测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24039704/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com