gpt4 book ai didi

javascript - Jasmine 单元测试与 postMessage 和 addEventListener

转载 作者:行者123 更新时间:2023-11-29 16:09:30 25 4
gpt4 key购买 nike

我正在尝试使用 postMessage 和 addEventListener 对情况进行单元测试。用例是我使用一个单独的窗口用于用户登录,类似于 OAuth 工作流,然后在登录窗口中使用 postMessage 通知主窗口用户已登录。这是主窗口中的监听代码:

$window.addEventListener("message", function(event) {
if (event.data.type === "authLogin") {
service.curUser = event.data.user;
utilities.safeApply($rootScope);
$window.postMessage({type: "authLoginSuccess"}, '*');
}
});

utilities.safeApply 函数定义为:

// Run $apply() if not already in digest phase.
utilitiesService.safeApply = function(scope, fn) {
return (scope.$$phase || scope.$root.$$phase) ? scope.$eval(fn) : scope.$apply(fn);
};

我的单元测试是为了发送一个postMessage来模拟登录:

describe('auth login postMessage', function() {
var testUser = {handle: 'test'};
beforeEach(function(done) {
$window.postMessage({type: 'authLogin', user: testUser}, '*');
function onAuthLoginSuccess(event) {
$window.removeEventListener('message', onAuthLoginSuccess);
done();
}
$window.addEventListener("message", onAuthLoginSuccess);
});
it("should set the user object", function() {
expect(service.curUser).toEqual(testUser);
});
});

这是运行单元测试的结果:

12 09 2015 14:10:02.952:INFO [launcher]: Starting browser Chrome
12 09 2015 14:10:05.527:INFO [Chrome 45.0.2454 (Mac OS X 10.10.5)]: Connected on socket 537CxfI4xPnR0yjLAAAA with id 12583721
Chrome 45.0.2454 (Mac OS X 10.10.5) ERROR
Uncaught Error: Unexpected request: GET security/loginModal.tpl.html
No more request expected
at http://localhost:8089/__test/Users/userX/esupport/code/proj/public/vendor/angular-mocks/angular-mocks.js:250
Chrome 45.0.2454 (Mac OS X 10.10.5): Executed 23 of 100 (skipped 60) ERROR (0.333 secs / 0.263 secs)

我不明白为什么它会尝试加载 HTML 模板。我已经缩小了它的范围,这样如果我不调用 $scope.$apply() 函数,单元测试就会成功而不会出错。但是,我需要 $apply() 来更新 View 。

我已经尝试在单元测试中删除 utilities.safeApply 方法,还尝试为 HTML 模板 GET 请求设置预期。这些尝试看起来像:

describe('auth login postMessage', function() {
var testUser = {handle: 'test'};
beforeEach(function(done) {
$httpBackend.when('GET', 'security/loginModal.tpl.html').respond(''); // <-- NEW
spyOn(utilities, 'safeApply').and.callFake(angular.noop); // <-- NEW
window.postMessage({type: 'authLogin', user: testUser}, '*');
function onAuthLoginSuccess(event) {
window.removeEventListener('message', onAuthLoginSuccess);
done();
}
window.addEventListener("message", onAuthLoginSuccess);
});
it("should set the user object", function() {
expect(service.curUser).toEqual(testUser);
});
});

这两种尝试都无济于事。我仍然收到相同的错误消息。我尝试了其他调试步骤,例如对 $location.path() 使用 spyOn,因此它返回一个示例值,如“/fake”。在我直接测试服务方法而不使用 postMessage 触发服务代码的所有其他单元测试中, stub 工作正常。但是,在 addEventListener 函数中,$location.path() 返回“”,这指向一个理论,即 addEventListener 函数在与单元测试准备的实例完全不同的实例中运行。这可以解释为什么没有使用被删除的函数以及为什么这个其他实例试图加载伪造的模板。这discussion也巩固了理论。

那么现在的问题是,我该如何让它发挥作用?即,如何让 addEventListener 函数在使用 stub 函数的同一实例中运行,并且它不向 HTML 模板发出请求?

最佳答案

我只是模拟所有外部部件并确保最终结果符合您的预期。

根据您的要点,您可能需要模拟更多服务,但这应该足以测试 “authLogin” 消息事件。

describe('some test', function() {
var $window, utilities, toaster, securityRetryQueue, service, listeners;

beforeEach(function() {
module('security.service', function($provide) {
$provide.value('$window',
$window = jasmine.createSpyObj('$window', ['addEventListener', 'postMessage']));
$provide.value('utilities',
utilities = jasmine.createSpyObj('utilities', ['safeApply']));
$provide.value('toaster',
toaster = jasmine.createSpyObj('toaster', ['pop']));
$provide.value('securityRetryQueue',
securityRetryQueue = jasmine.createSpyObj('securityRetryQueue', ['hasMore', 'retryReason']));

// make sure you're not fetching actual data in a unit test
securityRetryQueue.onItemAddedCallbacks = [];
securityRetryQueue.hasMore.and.returnValue(false);

$window.addEventListener.and.callFake(function(event, listener) {
listeners[event] = listener;
});
});

inject(function(security) {
service = security;
});
});

it('registers a "message" event listener', function() {
expect($window.addEventListener).toHaveBeenCalledWith('message', listeners.message, false);
});

it('message event listener does stuff', inject(function($rootScope) {
var event = {
data: {
type: 'authLogin',
user: 'user'
},
stopPropagation: jasmine.createSpy('event.stopPropagation')
};

listeners.message(event);

expect(service.curUser).toBe(event.data.user);
expect(toaster.pop).toHaveBeenCalledWith('success', 'Successfully logged in.');
expect(utilities.safeApply).toHaveBeenCalledWith($rootScope);
expect($window.postMessage).toHaveBeenCalledWith({type: "authLoginSuccess"}, '*');
expect(event.stopPropagation).toHaveBeenCalled();
}));
});

关于javascript - Jasmine 单元测试与 postMessage 和 addEventListener,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32544825/

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