2017-09-29 1 views
0

Ich versuche, eine Komponente zu testen, die Newsletter-Abonnements behandelt. Ich möchte testen, ob die submitForm-Funktion erfolgreich gespeichert wurde, indem ich nach dem Speichern eine Klasse einer versteckten Eingabe entsprechend gesetzt habe oder nicht, so dass ich dies in einem Integrationstest bestätigen kann.Ember-Komponente Integrationstest: inFlight Fehler beim Modell speichern

Hier ist mein Code:

newsletter.subscription.js:

<div class="ui container row newsletter-form"> 
    <div class="ui inverted segment"> 
    <form class="ui form" {{action "submitForm" on="submit"}}> 
     <div class="ui stackable grid"> 
     <div class="eleven wide right aligned column"> 
      {{input type='string' value=model.email placeholder=(t 'subscription.email')}} 
     </div> 
     <div class="five wide inverted left aligned column"> 
      <button type="submit" class="ui fluid secondary button {{unless model.email 'disabled'}}"> 
      {{t 'button.newsletter'}} 
      </button> 
     </div> 
     <input type='hidden' id="debug" class="{{subscribed}}" /> 
     </div> 
    </form> 
    </div> 
</div> 

Und:

import Ember from 'ember'; 

export default Ember.Component.extend({ 
    store: Ember.inject.service(), 
    displayNotifications: Ember.inject.service(), 

    didInsertElement() { 
    this.set('model', this.get('store').createRecord('subscription')); 
    }, 
    actions: { 
    submitForm() { 
     this.get('model').save().then(
     (json) => { 
      this.get('displayNotifications').success({ 
      key: 'subscription.success', 
      }); 
      this.set('model', this.get('store').createRecord('subscription')); 
      this.set('subscribed', true); 
     }, 
     (reason) => { 
      this.set('subscribed', 'error'); 
     }); 
    } 
    } 
}); 

Hier ist der Code derNewsletter-subscription.hbs ist Hier ist mein Test: newsletter-subscription-test.js

moduleForComponent('newsletter-subscription', 'Integration | Component | newsletter-subscription', { 
    integration: true 
}); 


test('newsletter-subscription: submitting newsletter-subscription sets subscribed to true', function(assert){ 

    this.render(hbs`{{newsletter-subscription subscribed='notSubscribed'}}`); 

    assert.equal(this.$('#debug').hasClass("notSubscribed"), true, 'before click, debug element has class notSubscribed'); 

    this.$('input[name=subscription-email]').val("[email protected]"); 
    this.$('button[type=submit]').click(); 

    return wait().then(() => { 
     assert.equal(this.$('#debug').hasClass("subscribed"), true, "after callback of click ran, debug element has class subscribed"); 
    }); 

}); 

Die erste Behauptung funktioniert. Aber dann bekomme ich immer einen Fehler:

✘ Assertion fehlgeschlagen: Sie können nur einen Datensatz entladen, die nicht inFlight ist.

Aus der Breakpoint-Analyse habe ich herausgefunden, dass dies passiert, wenn this.get ('model'). Save() aufgerufen wird. Meine Versuche, das Problem zu lösen, blieben bisher ineffektiv (d. H. Verspotten Server-Antwort mit Luftspiegelung). Gibt es in diesem Zusammenhang ein Problem mit der Ember-Run-Schleife, auf das ich irgendwie aufpassen muss oder etwas anderes?

Vielen Dank für Ihre Eingabe!

Antwort

0

Ich bin heute auf dieses Problem gestoßen; Das Kernproblem scheint zu sein, dass das Speichern von Datensätzen nicht funktionieren kann, da die App nicht in Integrations- und Komponententests ausgeführt wird. Es gibt zwei Möglichkeiten, um es:

  1. (bevorzugt) Stub save() auf die Modelle, die Sie in Ihre Komponenten passieren, mit Sinon. Zum Beispiel

    const record = new Ember.Object({ save: Sinon.spy(() => Ember.RSVP.resolve()) }; 
    this.render(hbs` 
        {{your-component record=record}} 
    `); 
    
  2. Wenn die oben ist keine Option - in meinem Fall, da der Datensatz in Ihrer Komponente erstellt wird, und Sie wollen nicht, dass die Schöpfung ein extrahieren gebenen in Methode (die die Reinigungs Option wäre), können Sie speichern das Verhalten außer Kraft setzen no-op zu machen spart, durch store.scheduleSave zwingende (wie durch Kelly Sutton, here beschrieben):

    this.inject.service('store'); 
    
    this.store.scheduleSave = function(context, resolver) { 
        resolver.resolve(context); 
    }; 
    

Es gibt sicherlich andere Wege, um dieses , einschließlich natürlich nur Wechsel zu einem acce Test, aber die beiden oben genannten sind wahrscheinlich die schnellsten Fixes.

Verwandte Themen