gpt4 book ai didi

javascript - 揭示测试的模块替代方案或变体

转载 作者:行者123 更新时间:2023-11-28 00:41:21 26 4
gpt4 key购买 nike

概述

我已经使用揭示模块模式几个月了,我正在寻找此模式的替代方案或变体,以解决我当前在事件处理程序和可测试性。我知道我可以想出下面的一些组合来解决我的问题,但我希望找到一个干净的替代方案,我可以持续使用它来解决我当前的两个问题。

揭示模块模式

因此,在这个示例中,我对事件处理程序没有任何问题,但我无法模拟对函数的调用在函数内进行隔离测试:

var Lion = (function () {

// Reference to rawr works as expected when the click event is triggered
function watch() {
document.addEventListener('click', rawr);
}

function rawr() {
console.log('rawr');
}

function attack() {
console.log('attack');
}

/*
* Can't test goCrazy() in isolation. Mocking rawr() and attack()
* has no effect as demonstrated below.
*/
function goCrazy() {
rawr();
attack();

// Important "crazy" logic
}

return {
watch: watch,
rawr: rawr,
attack: attack,
goCrazy: goCrazy
};
}());

module.exports = Lion;

示例测试用例(Jasmine)

describe('Mock Check', function () {

it('should mock rawr() and attack() and test only goCrazy logic', function () {
var lion = require('Lion');

spyOn(lion, 'rawr').and.reutrnValue(true);
spyOn(lion, 'attack').and.reutrnValue(true);

var crazy = lion.goCrazy();

expect(lion.rawr).toHaveBeenCalled(); // <-- Fails
expect(lion.attack).toHaveBeenCalled(); // <-- Fails

// can't test goCrazy() logic in isolation :(
});
});

使用 this 代替相同模块并使用 new 调用

在此示例中,我可以成功模拟对函数内函数的调用,但如果我尝试添加事件处理程序,则在触发事件时,this 会变为 undefined

var Lion = function () {

// Reference to 'this' becomes undefined when event is triggered
this.watch = function () {
document.addEventListener('click', this.rawr);
}

this.rawr = function () {
console.log('rawr');
}

this.attack = function () {
console.log('attack');
}

/*
* Can successfully test goCrazy() in isolation by being able to mock
* rawr() and attack() as needed
*/
this.goCrazy = function () {
this.rawr();
this.attack();

// Important "crazy" logic
}
};

module.exports = Lion;

示例测试用例(Jasmine)

describe('Mock Check', function () {

it('should mock rawr() and attack() and test only goCrazy logic', function () {
var Lion = require('Lion');
var lion = new Lion();

spyOn(lion, 'rawr').and.reutrnValue(true);
spyOn(lion, 'attack').and.reutrnValue(true);

var crazy = lion.goCrazy();

expect(lion.rawr).toHaveBeenCalled(); // <-- Success
expect(lion.attack).toHaveBeenCalled(); // <-- Success

// testing goCrazy logic in isolation :)
});
});

感谢您的宝贵时间。如果需要任何澄清,请告诉我,我将修改我的帖子。

最佳答案

这里的实际问题是,事件处理程序丢失了当前对象的上下文。你可以像这样绑定(bind)它

document.addEventListener('click', this.rawr.bind(this));

这将确保每当调用 rawr 时,rawr 内的 this 对应于 lion您创建的对象。

关于javascript - 揭示测试的模块替代方案或变体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27884028/

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