簡體   English   中英

在余燼Qunit測試中如何在集成測試中超越組件的功能

[英]How to over ride a function of component in integration test in ember Qunit testing

我在這里寫下我的第一個問題,對於任何歧義表示抱歉。

我寫一個集成測試update-pw組件,它簡單的渲染update-pw然后填寫輸入字段fillIn然后單擊保存按鈕,觸發動作savePWupdate-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.registerthis.application.inject 我不完全記得這是否是很久以前的做法,但是在Ember中已經有好幾年了。

我們最終要做的是從your-app-name/services/password-store導入StoreService (將您的應用程序名稱替換為modulePrefix所在的名稱),然后在覆蓋updateSingleUserPw()函數的同時對其進行擴展。 在您的示例中,您似乎試圖覆蓋一個名為savePW()的函數,但這實際上是該組件中的操作名稱,可能會使您感到有些困惑。

希望對您有所幫助,我已經在本地測試了示例,並且效果很好! 您可能還會注意到,我在服務內部添加了一個斷言,這對於確保服務從組件接收正確的參數是一種非常有用的模式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM