使用 Ember (cli) 如何获得验收测试以等待承诺? [英] Using Ember (cli) how do I get an acceptance test to wait for a promise?

查看:19
本文介绍了使用 Ember (cli) 如何获得验收测试以等待承诺?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的 Ember 应用程序中,我目前有一个模型,该模型具有一个 findResults 函数,该函数返回一个包装 Google Places 库以获取自动完成结果的承诺.为了在我的 UI 中使用它,我设置了一个 PromiseMixin 控制器.我指示控制器观察 searchText 值,当它发生变化时,我将控制器的承诺值更新为 findResults 函数返回的承诺,但使用来自搜索文本.当我在浏览器中玩应用程序时,这很好用,但是当我运行验收测试时,测试似乎在返回承诺之前完成,因此测试失败.我将在下面包含相关文件.

In my Ember app, I currently have a model that has a findResults function that returns a promise that is wrapping a Google Places library to fetch results for auto-completion. To use this in my UI, I setup a PromiseMixin controller. I instruct the controller to watch the searchText value, and when that changes I update the controller's promise value to be the promise returned by the findResults function, but with the new value from searchText. This works nicely when I'm playing with the app in the browser, however when I run my acceptance tests the test seems to finish before the promise is returned and therefore the tests fail. I'll include the relevant files below.

我不知道如何告诉 Ember 在测试期间等待承诺解决.

I'm not sure how to tell Ember to wait for the promise to resolve during testing.

app/services/google-autocomplete-location.js

import Ember from "ember";

var googleAutocompleteLocation = Ember.Object.extend({
  placeId: null,
  description: null
});

googleAutocompleteLocation.reopenClass({
  findResults: function(query) {
    var self = this;
    var promise = new Ember.RSVP.Promise(function(resolve, reject) {
      var autocompleteService = new google.maps.places.AutocompleteService();

      return autocompleteService.getPlacePredictions({ input: query },
        function(predictions, status) {
          if (status !== google.maps.places.PlacesServiceStatus.OK) {
            Ember.run(null, reject, status);
          }
          else {
            Ember.run(null, resolve, self._decorateGoogleResults(predictions));
          }
        });
    });

    return promise;
  },

  _decorateGoogleResults: function(predictions) {
    var locations = [];

    predictions.forEach(function(prediction) {
      locations.push(
        googleAutocompleteLocation.create({
          placeId: prediction.place_id,
          description: prediction.description
        })
      );
    });


    return locations;
   }
});

export default googleAutocompleteLocation;

app/controllers/index.js

import Ember from "ember";
import GoogleLocation from "../services/google-location";
import GoogleAutocompleteLocation from '../services/google-autocomplete-location';

export default Ember.ArrayController.extend(Ember.PromiseProxyMixin, {
  searchText: '',
  map: null,
  mapUrl: null,

  actions: {
    submit: function() {
      return this.transitionToRoute('entries.new');
    }
  },

  highlightedResult: function() {
    if (this.get('model').length) {
      return this.get('model')[0];
    } else {
      return null;
    }
  }.property('model'),

  setMap: (function() {
    if (this.get('highlightedResult') === null) {
      return this.set('map', null);
    } else {
      if (this.get('map') === null) {
        return this.set('map', GoogleLocation.create({
          mapContainer: Ember.$('.maps-info'),
          placeId: this.get('highlightedResult').placeId
        }));
      } else {
        return this.get('map').set('placeId', this.get('highlightedResult').placeId);
      }
    }
  }).observes('highlightedResult'),

  searchTextChanged: (function() {
    if (this.get('searchText').length) {
      this.set('promise',
        GoogleAutocompleteLocation.findResults(this.get('searchText')));
      console.log(this.get('promise'));
    } else {
      this.set('model', []);
    }
  }).observes('searchText')
});

tests/acceptance/create-new-entry-test.js

test('finding a location', function() {
  expect(1);
  visit('/');
  click('.location-input input');
  fillIn('.location-input input', "Los Angeles, CA");

  andThen(function() {
    var searchResult = find('.search-results ul li:first a').text();

    equal(searchResult, 'Los Angeles, CA, United States');
  });
});

推荐答案

解决此问题的最佳方法可能是注册您自己的异步测试助手.我已经准备了一个 JSBin 模拟你的代码和一个解决方案:http://jsbin.com/ziceratana/3/edit?html,js,output

The best way to go about this is likely to register your own async test helper. I've prepared a JSBin with a simulation of your code and a solution here: http://jsbin.com/ziceratana/3/edit?html,js,output

用于创建助手的代码是这样的:

The code used to create the helper is this:

Ember.Test.registerAsyncHelper('waitForControllerWithPromise', function(app, controllerName) {
  return new Ember.Test.promise(function(resolve) {

    // inform the test framework that there is an async operation in progress,
    // so it shouldn't consider the test complete
    Ember.Test.adapter.asyncStart();

    // get a handle to the promise we want to wait on
    var controller = app.__container__.lookup('controller:' + controllerName);
    var promise = controller.get('promise');

    promise.then(function(){

      // wait until the afterRender queue to resolve this promise,
      // to give any side effects of the promise resolving a chance to
      // occur and settle
      Ember.run.schedule('afterRender', null, resolve);

      // inform the test framework that this async operation is complete
      Ember.Test.adapter.asyncEnd();
    });
  });
});

它会像这样使用:

test('visiting / and searching', function() {
  expect(1);
  visit('/');
  click('.location-input input');
  fillIn('.location-input input', "Los Angeles, CA");
  waitForControllerWithPromise('index'); // <-- simple & elegant!
  andThen(function(){
    var searchResult = find('.search-results ul li:first').text();
    equal(searchResult, 'Los Angeles, CA, United States');
  });
});

在 ember-testing 中,async-helper 会自动等待之前的 promises,后续的 async helper 会在测试执行时等待它.有关这方面的优秀背景,请参阅 Cory Forsyth 的揭秘异步测试

In ember-testing, an async-helper will automatically wait on previous promises and subsequent async helpers will wait on it when the test is executed. For excellent background on this, see Cory Forsyth's Demystifying Async Testing

这篇关于使用 Ember (cli) 如何获得验收测试以等待承诺?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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