实例初始化单元测试失败,“store is undefined” [英] Instance initializer unit test fails with "store is undefined"

查看:402
本文介绍了实例初始化单元测试失败,“store is undefined”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

生成示例应用程序后:

ember new preloadtest
cd preloadtest/
ember g instance-initializer preload
ember g model test-data
ember g route index
ember g adapter application

使用以下文件:

models / test-data.js

import DS from 'ember-data';

export default DS.Model.extend({
  name: DS.attr('string'),
  value: DS.attr( 'number' )
});

routes / index.js

import Ember from 'ember';

export default Ember.Route.extend({
  model(){
    return this.store.peekAll( 'test-data' );
  }
});

instance-initializers / preload.js

export function initialize( appInstance ) {
  let store = appInstance.lookup( 'service:store' );
  store.pushPayload( { "testDatas": [
    { "id": 1, "name": "aaa", "value": 1},
    { "id": 2, "name": "bbb", "value": 2},
    { "id": 3, "name": "ccc", "value": 3}
  ] } );
}

export default {
  name: 'preload',
  initialize
};

templates / index.hbs

<ul>
{{#each model as |td|}}
  <li>{{td.name}}: {{td.value}}</li>
{{/each}}
</ul>

适配器/ application.js

import RESTAdapter from 'ember-data/adapters/rest';

export default RESTAdapter.extend({});

ember serve 运行应用程序并显示预加载数据,但进入 / tests preload 实例初始化程序的默认单元测试失败,错误 store is undefined

ember serve runs the application and displays the preload data but going to /tests the default unit test for the preload instance initializer fails with the error store is undefined.

完整错误消息

Died on test #1 @http://localhost:4200/assets/tests.js:212:1
Module.prototype.exports@http://localhost:4200/assets/vendor.js:94:20
Module.prototype.build@http://localhost:4200/assets/vendor.js:142:5
findModule@http://localhost:4200/assets/vendor.js:193:5
requireModule@http://localhost:4200/assets/vendor.js:181:12
TestLoader.prototype.require@http://localhost:4200/assets/test-loader.js:67:9
TestLoader.prototype.loadModules@http://localhost:4200/assets/test-loader.js:58:13
TestLoader.load@http://localhost:4200/assets/test-loader.js:89:7
@http://localhost:4200/assets/test-support.js:6397:5
: store is undefined@ 114 ms
Source:     

initialize@http://localhost:4200/assets/preloadtest.js:213:5
@http://localhost:4200/assets/tests.js:213:1
runTest@http://localhost:4200/assets/test-support.js:2716:14
Test.prototype.run@http://localhost:4200/assets/test-support.js:2701:4
run/<@http://localhost:4200/assets/test-support.js:2843:6
process@http://localhost:4200/assets/test-support.js:2502:4
begin@http://localhost:4200/assets/test-support.js:2484:2
resumeProcessing/<@http://localhost:4200/assets/test-support.js:2544:4

我初始化应用程序的存储,以便它可以在单元测试中使用。

How do I initialize the application's store so that it can be used in the unit test?

编辑 - 测试/单元/实例初始化/预加载测试/ strong>

Edit - tests/unit/instance-initializers/preload-test.js

import Ember from 'ember';
import { initialize } from 'preloadtest/instance-initializers/preload';
import { module, test } from 'qunit';
import destroyApp from '../../helpers/destroy-app';
//import DS from 'ember-data';

module('Unit | Instance Initializer | preload', {
  //needs: [ 'service:store' ],
  beforeEach: function() {
    Ember.run(() => {
      this.application = Ember.Application.create();
      this.appInstance = this.application.buildInstance();
    });
  },
  afterEach: function() {
    Ember.run(this.appInstance, 'destroy');
    destroyApp(this.application);
  }
});

// Replace this with your real tests.
test('it works', function(assert) {
  initialize(this.appInstance);

  // you would normally confirm the results of the initializer here
  assert.ok(true);
});

尝试使用需求:['service:store'] 和没有(虽然它建议你不应该这样做如果Ember -Data在页面上 - 我也尝试在单元测试和实例初始化器中导入)。

Tried it with needs: [ 'service:store' ] and without (although its suggested that you should not need to do this if Ember-Data is on the page - which I've also tried importing both in the unit test and in the instance initialiser).

版本

Ember      : 2.4.5
Ember Data : 2.5.2


推荐答案

在实例初始化程序的单元测试中,您不需要实现存储服务。在这种情况下,更喜欢使用模拟服务。您的实例初始化程序的行为是将某些数据放入应用程序提供的存储中。

At Unit test of an instance-initializer, you don't need to get real store service. In such cases, prefer using mock services. The behaviour of your instance-initializer is to put some data to the store which is provided by application. You can easily mock that store.

具有模拟服务的示例测试代码:

Example test code with mock service:

import Ember from 'ember';
import { initialize } from 'preloadtest/instance-initializers/preload';
import { module, test } from 'qunit';
import destroyApp from '../../helpers/destroy-app';

//this is the mock store service:
const storeStubFactory  = Ember.Service.extend({
  data: null,
  init(){
    this.data = [];
  },
  pushPayload(payload){
      this.get('data').pushObject(payload); 
  },
  getAllPayloads(){
      return this.get('data');
  }
});

module('Unit | Instance Initializer | preload', {
  beforeEach: function() {
    Ember.run(() => {
      this.application = Ember.Application.create();
      this.appInstance = this.application.buildInstance();
      //Register your mock service (do not  create instance, use factory)
      this.appInstance.register('service:store', storeStubFactory);
    });
  },
  afterEach: function() {
    Ember.run(this.appInstance, 'destroy');
    destroyApp(this.application);
  }
});

// This is your real test:
test('it works', function(assert) {
  initialize(this.appInstance);

  // confirm that mock service has the correct payload:      
  assert.ok(this.appInstance.lookup('service:store').getAllPayloads());
});

第二个选项

当然,你也可以模拟 initialize 函数的 appInstance 参数,如下所示:

Of course you can also mock the appInstance paramater of the initialize function as below:

import Ember from 'ember';
import { initialize } from 'preloadtest/instance-initializers/preload';
import { module, test } from 'qunit';
import destroyApp from '../../helpers/destroy-app';

const storeStubFactory  = Ember.Service.extend({
  data: null,
  init(){
    this.data = [];
  },
  pushPayload(payload){
      this.get('data').pushObject(payload); 
  },
  getAllPayloads(){
      return this.get('data');
  }
});

module('Unit | Instance Initializer | preload');

// This is your real test:
test('it works', function(assert) {
  let instance = storeStubFactory.create();

  initialize({lookup:function(serviceName){return serviceName==='service:store' ? instance : null;}}); 

  // confirm that mock service has the correct payload:   
  assert.ok(instance.getAllPayloads());
});

但我更喜欢使用第一个。我们表示您的实例初始化器行为为将应用程序提供的某些数据放入商店。但是在第二个选项中,似乎我们也在检查您的实例初始化程序是否也调用appInstance 的查找功能。此测试更符合您的实施细节。

But I prefer to use first one. We stated that your instance-initializers behaviour as to put some data to the store which is provided by application. But in second option, it seems that we are also checking that your instance-initializer is calling the lookup function of appInstance too. This test is more coupled to your implementation detail.

这篇关于实例初始化单元测试失败,“store is undefined”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆