我认真的新手在JavaScript的单元测试,我试图找出如何解决这个问题,这就是情况:我为addEventListener创建了一个新函数来防止使用按键'输入'的所有问题是在Newsletter.js我们正在从html页面获取所有表格,并保存在新值this.terms只能在with编号=“#术语”,但我需要在单元测试中创建所有的表单,我试图为新函数做单元测试,但是...我不知道如何为此单元测试部分,因为在吞咽测试中我有这样的回应:Javascript单元测试addEventListener它不是一个函数
HeadlessChrome 0.0.0 (Mac OS X 10.12.6) Newsletter component specification test somthing FAILED
TypeError: Cannot read property 'addEventListener' of null
at new Newsletter (app/Resources/assets/enterprise/js/core/components/Newsletter.js:9:1025)
at Context.<anonymous> (app/Resources/assets/enterprise/js/test/specs/core/components/Newsletter.spec.js:48:5)
LOG: Object{querySelectorAll: function() { ... }, querySelector: function (element) { ... }, submit: submit}
LOG: 'terms'
LOG: <input id="terms" type="checkbox">
HeadlessChrome 0.0.0 (Mac OS X 10.12.6) Newsletter component specification should submit newsletter subscription with female gender FAILED
TypeError: this.handler.addEventListener is not a function
at new Newsletter (app/Resources/assets/enterprise/js/core/components/Newsletter.js:9:1469)
at Context.<anonymous> (app/Resources/assets/enterprise/js/test/specs/core/components/Newsletter.spec.js:73:5)
at f (node_modules/sinon-test/dist/sinon-test.js:1:1331)
at Context.<anonymous> (node_modules/sinon-test/dist/sinon-test.js:1:1678)
LOG: Object{querySelectorAll: function() { ... }, querySelector: function (element) { ... }, submit: submit}
LOG: 'terms'
LOG: <input id="terms" type="checkbox">
HeadlessChrome 0.0.0 (Mac OS X 10.12.6) Newsletter component specification should enabled buttons newsletter when accepted terms and conditions FAILED
TypeError: this.handler.addEventListener is not a function
at new Newsletter (app/Resources/assets/enterprise/js/core/components/Newsletter.js:9:1469)
at Context.<anonymous> (app/Resources/assets/enterprise/js/test/specs/core/components/Newsletter.spec.js:84:5)
at f (node_modules/sinon-test/dist/sinon-test.js:1:1331)
at Context.<anonymous> (node_modules/sinon-test/dist/sinon-test.js:1:1678)
LOG: Object{querySelectorAll: function() { ... }, querySelector: function (element) { ... }, submit: submit}
LOG: 'terms'
LOG: <input id="terms" type="checkbox">
HeadlessChrome 0.0.0 (Mac OS X 10.12.6) Newsletter component specification should enabled buttons newsletter when accepted terms and conditions FAILED
TypeError: this.handler.addEventListener is not a function
at new Newsletter (app/Resources/assets/enterprise/js/core/components/Newsletter.js:9:1469)
at Context.<anonymous> (app/Resources/assets/enterprise/js/test/specs/core/components/Newsletter.spec.js:93:5)
at f (node_modules/sinon-test/dist/sinon-test.js:1:1331)
at Context.<anonymous> (node_modules/sinon-test/dist/sinon-test.js:1:1678)
LOG: Object{querySelectorAll: function() { ... }, querySelector: function (element) { ... }, submit: submit}
LOG: 'terms'
LOG: <input id="terms" type="checkbox">
HeadlessChrome 0.0.0 (Mac OS X 10.12.6) Newsletter component specification should submit newsletter subscription with male gender FAILED
TypeError: this.handler.addEventListener is not a function
at new Newsletter (app/Resources/assets/enterprise/js/core/components/Newsletter.js:9:1469)
at Context.<anonymous> (app/Resources/assets/enterprise/js/test/specs/core/components/Newsletter.spec.js:103:5)
at f (node_modules/sinon-test/dist/sinon-test.js:1:1331)
at Context.<anonymous> (node_modules/sinon-test/dist/sinon-test.js:1:1678)
ERROR: 'Exception in queued GPT command', TypeError{}
所以...说实话我没有想法来解决这个错误,我没有任何单元测试的经验,如果有人能帮我解决这个部分,我会非常感激的,代码是在这里:
footer.twig.html
<form class="col-lg-9 col-md-6 col-sm-12 col-xs-12" action="{{ path('frontend.newsletter.subscribe') }}" method="POST" data-newsletter>
<div class="row">
<div class="col-lg-6 col-xs-12">
<input type="email" name="promotional_newsletter_form[email]" placeholder="{{ 'newsletter.subscribe_with_your_email'|trans }}" class="row form-control form-control-sm" />
<div class="checkbox">
<label>
<input id="terms" type="checkbox">{{ 'NEWSLETTER_TERMS_AND_CONDITIONS_1'|trans }}
<a href="{{ terms_and_conditions }}" target="_blank">{{ 'NEWSLETTER_TERMS_AND_CONDITIONS_2'|trans }} ashdfjlhasdfjahsjfdk</a>
</label>
</div>
<input type="hidden" name="promotional_newsletter_form[gender]" />
</div>
<div class="col-lg-3 col-md-6 col-xs-12">
<button type="submit" class="btn btn-default btn-sm col-xs-12" data-gender="male">{{ 'newsletter.male_deals'|trans }}</button>
</div>
<div class="col-lg-3 col-md-6 col-xs-12">
<button type="submit" class="btn btn-default btn-sm col-xs-12" data-gender="female">{{ 'newsletter.female_deals'|trans }}</button>
</div>
</div>
</form>
core.js:
window.addEventListener('load', function() {
backdrop = new Backdrop(document.getElementById('backdrop'));
loader = new Loader(document.getElementById('loader'));
new AlertModal(document.getElementById('alert-modal'));
$('[data-newsletter]').each(function (element) {
new Newsletter(element);
});
window.DY = window.DY || {};
window.DY.API = function() {
(DY.API.actions = DY.API.actions || []).push(arguments);
};
window.DY.API('callback', function() {
var smartObjects = document.querySelectorAll('[data-dyso]');
for (var i = 0; i < smartObjects.length; i++) {
DYO.smartObject(smartObjects[i].dataset.dyso, { target: smartObjects[i].id, inline: true });
}
});
for (var i = 0; i < lsfConfig.thirdPartyModules.length; i++) {
var js = document.createElement('script');
js.src = lsfConfig.thirdPartyModules[i];
document.body.appendChild(js);
}
});
Newsletter.js
这部分是我创建一个新函数,以防止用户使用'回车'提交新闻稿,因为它发送了错误的信息,但我检查有两种方法来阻止用户提交输入没有选择按钮,在this.terms来选择输入,但我想使用所有的形式不是特定的querySelector #terms所以,这就是为什么我使用this.handler。的addEventListener应用所有形式
var Newsletter = (function() {
function Newsletter(handler) {
this.handler = handler;
this.submitButtons = this.handler.querySelectorAll('[type="submit"]');
this.genderInput = this.handler.querySelector('[name="promotional_newsletter_form[gender]"]');
this.terms = this.handler.querySelector('#terms');
this.subscribe = this.subscribe.bind(this);
this.acceptTerms = this.acceptTerms.bind(this);
this.enableButtons = this.enableButtons.bind(this);
this.disableButtons = this.disableButtons.bind(this);
this.preventEnter = this.preventEnter.bind(this);
this.terms.addEventListener('click', this.acceptTerms);
for (var i = 0; i < this.submitButtons.length; i++) {
this.submitButtons[i].disabled = true;
}
console.log(this.handler);
console.log('terms');
console.log(this.terms);
this.handler.addEventListener('keypress', this.preventEnter, false);
}
Newsletter.prototype.acceptTerms = function acceptTerms() {
if (this.terms.checked) {
this.enableButtons();
return;
}
this.disableButtons();
};
**/////////////////////////////////////////////////////
// New function to prevent keypress 'enter'
/////////////////////////////////////////////////////**
Newsletter.prototype.preventEnter = function preventEnter(e) {
var key = e.charCode || e.keyCode || 0;
if (key === 13) {
e.preventDefault();
}
};
Newsletter.prototype.enableButtons = function enableButtons() {
for (var i = 0; i < this.submitButtons.length; i++) {
this.submitButtons[i].disabled = false;
this.submitButtons[i].addEventListener('click', this.subscribe);
}
};
Newsletter.prototype.disableButtons = function disableButtons() {
for (var i = 0; i < this.submitButtons.length; i++) {
this.submitButtons[i].disabled = true;
this.submitButtons[i].removeEventListener('click', this.subscribe);
}
};
Newsletter.prototype.subscribe = function subscribe(event) {
event.preventDefault();
var element = event.target || event.srcElement;
if (this.genderInput) {
this.genderInput.value = element.dataset.gender;
}
this.handler.submit();
};
return Newsletter;
})();
所有代码的工作很细,没有任何问题,和“的addEventListener”的作品,因为它使用“ENTER”键防止给用户,但是当我试图对特定部分做单元测试:
Newsletter.spec.js
*this.handler.addEventListener('keypress', this.preventEnter, false);
Newsletter.prototype.preventEnter = function preventEnter(e) {
var key = e.charCode || e.keyCode || 0;
if (key === 13) {
e.preventDefault();
}
};*
在单元测试,我很不可思议卡住,我的想法如何推进......所以......这里的单元测试:
describe('Newsletter component specification', function() {
var form;
var genderInput;
var maleButton;
var femaleButton;
var terms;
var keyPressed = null;
var form1; **// new value to createElement form**
beforeEach(function() {
form1 = document.createElement('form'); **// obtain all the form by the handler**
genderInput = document.createElement('input');
genderInput.type = 'hidden';
genderInput.name = 'promotional_newsletter_form[gender]';
terms = document.createElement('input');
terms.id = 'terms';
terms.type = 'checkbox';
maleButton = document.createElement('button');
maleButton.dataset.gender = 'male';
maleButton.type = 'submit';
femaleButton = document.createElement('button');
femaleButton.dataset.gender = 'female';
femaleButton.type = 'submit';
form = {
querySelectorAll: function() {
return [maleButton, femaleButton];
},
querySelector: function (element) {
if (element === '#terms') {
return terms;
}
return genderInput;
},
submit: function() {},
};
form1 = document.createElement(form); // trying to convert all the form Object to DOM ??
});
it('test somthing', function() {
new Newsletter(form1);
});
// UNIT TEST OF ADDEVENTLISTENER... works or not ?
it('should intercept enter keypress event and prevent it', function() {
function keyPress(key) {
var event = document.createEvent('Event');
event.keyCode = key;
event.initEvent('keypress');
document.dispatchEvent(event);
}
document.addEventListener('keypress', function (e) {
keyPressed = e.keyCode;
});
keyPress(13);
expect(keyPressed).to.be.equal(13);
});
it('should submit newsletter subscription with female gender', sinon.test(function() {
var formSubmitCall = sinon.stub(form, 'submit').returns(false);
new Newsletter(form);
terms.click();
femaleButton.click();
assert(formSubmitCall.called);
expect(genderInput.value).to.be.equal('female');
}));
it('should enabled buttons newsletter when accepted terms and conditions', sinon.test(function() {
var formSubmitCall = sinon.stub(form, 'submit').returns(false);
new Newsletter(form);
terms.click();
expect(maleButton.disabled).to.be.equal(false);
}));
it('should enabled buttons newsletter when accepted terms and conditions', sinon.test(function() {
var formSubmitCall = sinon.stub(form, 'submit').returns(false);
new Newsletter(form);
terms.click();
terms.click();
expect(maleButton.disabled).to.be.equal(true);
}));
it('should submit newsletter subscription with male gender', sinon.test(function() {
var formSubmitCall = sinon.stub(form, 'submit').returns(false);
new Newsletter(form);
terms.click();
maleButton.click();
assert(formSubmitCall.called);
expect(genderInput.value).to.be.equal('male');
}));
afterEach(function() {
form = null;
genderInput.remove();
genderInput = null;
maleButton.remove();
maleButton = null;
femaleButton.remove();
femaleButton = null;
});
});