[英]How to over ride a function of component in integration test in ember Qunit testing
我在這里寫下我的第一個問題,對於任何歧義表示抱歉。
我寫一個集成測試update-pw
組件,它簡單的渲染update-pw
然后填寫輸入字段fillIn
然后單擊保存按鈕,觸發動作savePW
在update-pw.js
。 我只通過email
(我們要為其更改密碼的人)和new password
。
savePW()
函數還具有一個調用self.store.updateSingleUserPw(email, newPw)
的函數self.store.updateSingleUserPw(email, newPw)
該函數編寫在服務store.js
。
服務器調用API之后updateSingleUserPw(email, newPw)
返回一個updateSingleUserPw(email, newPw)
。 在履行或拒絕諾言的基礎上,我表現出一種模態。 我只想在測試中使該承諾實現或拒絕,而不是服務器對承諾的響應。
// integration/component/update-pw-test.js
import { module, test } from 'qunit';
import EmberObject from '@ember/object';
import { setupRenderingTest } from 'ember-qunit';
import { render, fillIn, click } from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';
import Service from '@ember/service';
module('Integration | Component | update-pw', function(hooks) {
setupRenderingTest(hooks);
const store = Service.extend({
savePW() {
self.store.updateSingleUserPw(email, newPw, function() {
console.log('this is function overriding', email, newPw);
return true;
})
.then(function() {
// Reset controller fields
self.set('password', '');
self.set('updateModal', false);
swal({
title: 'Das hat geklappt',
type: 'success'
});
}, function() {
self.set('updateModal', false);
swal({
title: 'problems with setting new pw.',
type: 'error'
});
})
.finally(function() {
self.set('changingPassword', false);
});
}
});
test('it renders', async function(assert) {
this.application.register('service:store', store);
this.application.inject.service('store', { as: 'store' });
assert.expect(2);
this.set('updateModal', true);
this.set('testing', true);
let currentUpdateAdmin = EmberObject.create({
username: 'steinauer',
email: 'lala@test.at'
});
this.set('currentUpdateAdmin', currentUpdateAdmin);
await render(hbs`{{update-pw updateModal=updateModal currentUpdateAdmin=currentUpdateAdmin testing=testing store=store}}`);
assert.equal(this.element.querySelector('h4').textContent.trim(), 'set new PW for steinauer');
await fillIn('#password', 'test123456');
await click('.save-button');
// Template block usage:
await render(hbs`
{{#update-pw}}
template block text
{{/update-pw}}
`);
// assert.equal(this.element.textContent.trim(), 'what is this');
});
});
// components/update-pw.js
import Component from '@ember/component';
export default Component.extend({
changingPassword: false,
actions: {
savePW() {
let self = this;
if (!self.get('currentUpdateAdmin.email'))
return;
let newPw = self.get('password');
let email = self.get('currentUpdateAdmin.email');
self.set('changingPassword', true);
if (!email)
return;
self.store.updateSingleUserPw(email, newPw)
.then(function() {
// Reset controller fields
self.set('password', '');
self.set('updateModal', false);
swal({
title: 'Das hat geklappt',
type: 'success'
});
}, function() {
self.set('updateModal', false);
swal({
title: 'problems with setting new pw',
type: 'error'
});
})
.finally(function() {
self.set('changingPassword', false);
});
}
}
});
在Service/store.js
功能:
updateSingleUserPw(email, newPw) {
let headers = this.get('headers');
return new Promise(function(resolve, reject) {
$.ajax({
type: 'POST',
url: ENV.api + '/accounts/updateSingleUserPw',
data: {
email: email,
pwNew: newPw
},
headers,
dataType: 'json'
}).then(function(success) {
if (success) {
resolve(newPw);
} else {
reject('password change failed');
}
}, function(xhr, status, error) {
reject(error);
});
});
}
在嘗試覆蓋函數之前,我只拒絕了Promise模態,但是在嘗試覆蓋函數之后,我得到了:在“它呈現”期間被拒絕的承諾:無法讀取未定義的屬性register
。
謝謝你的問題🎉
首先,我要感謝您提供的代碼示例,如果您提供的示例太多,我將無法解決您的問題! 實際上,我已經簡化了您要嘗試做的一些事情,並且我認為通過簡化可以解決問題的事情。
首先,我將您一直使用的服務重命名為password-store
。 通常,當Ember開發人員看到名為“服務”的store
他們傾向於想到一個余燼數據存儲,我假設您實際上並沒有按照期望的功能在這里使用它。
我生成了一個非常簡單的模擬存儲,其中只有一個功能:
// app/services/password-store.js
import Service from '@ember/service';
export default Service.extend({
updateSingleUserPw(email, password) {
// TODO: do something with email & password
return Promise.resolve();
}
});
這只是返回一個承諾,因此不會破壞任何其他代碼示例。 然后,我更新了您的update-pw
組件以使用新的密碼存儲區:
// app/components/update-pw.js
import Component from '@ember/component';
import { inject as service } from '@ember/service';
function swal() {
// noop - not sure where this comes from
}
export default Component.extend({
passwordStore: service(),
changingPassword: false,
actions: {
savePW() {
if (!this.get('currentUpdateAdmin.email'))
return;
let newPw = this.get('password');
let email = this.get('currentUpdateAdmin.email');
this.set('changingPassword', true);
if (!email)
return;
this.passwordStore.updateSingleUserPw(email, newPw)
.then(() => {
// Reset controller fields
this.set('password', '');
this.set('updateModal', false);
swal({
title: 'Das hat geklappt',
type: 'success'
});
}, () => {
this.set('updateModal', false);
swal({
title: 'problems with setting new pw',
type: 'error'
});
})
.finally(() => {
this.set('changingPassword', false);
});
}
}
});
我還添加了swal()
函數,因為我不太了解示例中的內容。 它似乎丟失了,所以我忽略了它。
現在,我終於設置了一個模板,以便測試可以通過:
// app/templates/components/update-pw.hbs
<h4>set new PW for steinauer</h4>
{{input id="password" value=password}}
<button type="button" name="button" class="save-button" {{action 'savePW'}}></button>
現在,隨着應用程序的完全設置,這里是一個完整的測試示例,它將完全按照您希望的方式進行:
// tests/integration/components/update-pw-test.js
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render, fillIn, click } from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';
import StoreService from 'your-app-name/services/password-store';
module('Integration | Component | update-pw', function(hooks) {
setupRenderingTest(hooks);
test('it renders', async function(assert) {
const passwordStore = StoreService.extend({
updateSingleUserPw(email, newPw) {
console.log('updateSingleUserPw override!!');
assert.equal(newPw, 'test123456');
return Promise.resolve();
}
});
this.owner.register('service:password-store', passwordStore);
assert.expect(2);
this.set('updateModal', true);
this.set('testing', true);
let currentUpdateAdmin = {
username: 'steinauer',
email: 'lala@test.at'
};
this.set('currentUpdateAdmin', currentUpdateAdmin);
await render(hbs`{{update-pw updateModal=updateModal currentUpdateAdmin=currentUpdateAdmin testing=testing store=store}}`);
assert.equal(this.element.querySelector('h4').textContent.trim(), 'set new PW for steinauer');
await fillIn('#password', 'test123456');
await click('.save-button');
// Template block usage:
await render(hbs`
{{#update-pw}}
template block text
{{/update-pw}}
`);
});
});
您可能會注意到的第一件事是我們沒有使用this.application.register
或this.application.inject
。 我不完全記得這是否是很久以前的做法,但是在Ember中已經有好幾年了。
我們最終要做的是從your-app-name/services/password-store
導入StoreService
(將您的應用程序名稱替換為modulePrefix
所在的名稱),然后在覆蓋updateSingleUserPw()
函數的同時對其進行擴展。 在您的示例中,您似乎試圖覆蓋一個名為savePW()
的函數,但這實際上是該組件中的操作名稱,可能會使您感到有些困惑。
希望對您有所幫助,我已經在本地測試了示例,並且效果很好! 您可能還會注意到,我在服務內部添加了一個斷言,這對於確保服務從組件接收正確的參數是一種非常有用的模式。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.