我認真的新手在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;
});
});