# Guide: Asynchronous side-effects in testing

**URL:** https://discuss.emberjs.com/t/guide-asynchronous-side-effects-in-testing/2905
**Category:** Uncategorized
**Created:** [October 8, 2013, 3:28pm UTC](https://discuss.emberjs.com/t/guide-asynchronous-side-effects-in-testing/2905 "2013-10-08T15:28:16Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![tarasm](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/tarasm/32/15980_2.png) [@tarasm](https://discuss.emberjs.com/u/tarasm)
#### Post date: [October 8, 2013, 3:28pm UTC](https://discuss.emberjs.com/t/guide-asynchronous-side-effects-in-testing/2905/1 "2013-10-08T15:28:17Z")

</div>

> Assertion failed: You have turned on testing mode, which disabled the run-loop’s autorun. You will need to wrap any code with asynchronous side-effects in an Ember.run

I would like to make it easier for people to understand what to do when they encounter this message by creating a guide that will explain what this message means and what they can do about it. Also, this guide will include description of the kinds of asynchronous calls that need to be wrapped in `Ember.run` and which do not.

**I understand this problem in the following way:**

**In normal operation** , Ember applications run asynchronously. This means that the application doesn’t run as a predefined sequence of operations, but rather a dynamic series of events and a queue of operations for each event. This is referred to as the Ember _RunLoop_ and manages the order of fired events(scheduling), eliminating unnecessary duplicate events(debouncing) and making sure that all operations are executed.

The _RunLoop_ has 2 methods **Ember.run.begin()** and **Ember.run.end()**. `Ember.run.begin()` causes the _RunLoop_ to start listening for asynchronous calls. `Ember.run.end()` starts the _RunLoop_. When started, the _RunLoop_ will cycle through all of the events, executing all of the operations until the queues are depleted.

**When testing** , you want to run each test in isolation and after asynchronous operations are executed. To do this, Ember disables the _RunLoop_ assuming that any code that has _asynchronous side-effects_ will call start the _RunLoop_ when necessary.

To manually start the run loop, wrap your code with `Ember.run( / **your code** / )`.

```javascript
Ember.run(function(){
  // all call that results in asynchronous operations goes here
});

// or

Ember.run( / **object** /, / **method name** /, / **arg1** /, / **arg2** / );

```

**WARNING** If you’re not careful or when using 3rd party plugins, its possible to introduce an asynchronous side effect that is called after RunLoop finishes. If you do this, wrapping your code in Ember.run will still produce the assert warning.

For example, using setTimeout with a callback that relies on the RunLoop maybe produce assert warning.

```javascript
/**
 * BAD: may produce assert message because Em.Object.create() may run after RunLoop finishes
 */
var callbackWithAsyncSideEffect = function() {
   return Em.Object.create();
}

Ember.run(function(){
  setTimeout(callbackWithAsyncSideEffect, 3000);
});

```

You can eliminate this message by wrapping Em.Object.create() in Ember.run().

```javascript
/**
 * BETTER: assert message will not be produced but still using setTimeout
 */
var callbackWithAsyncSideEffect = function() {
   var created;
   Ember.run(function(){
       created = Em.Object.create({});
   });
   return Em.Object.create({}); // this call requires RunLoop and will create an assert message
   /**
    * BETTERER: do it in one line without assert message but still using setTimeout
    * return Ember.run( Em.Object, 'create', {} );
    */
}

Ember.run(function(){
  setTimeout(callbackWithAsyncSideEffect, 3000);
});

```

**BEST** : Eliminate setTimeout and use `Ember.run.scheduleOnce( / **action** /, / **object** /, / **method** / )` to schedule the callback to execute at the appropriate moment in the RunLoop.

```javascript
Ember.run.scheduleOnce('afterRender', this, 'callbackWithAsyncSideEffect');

```

_I’m looking for a complete list of queues that can be used, if you have it, let me know._

**What happens in production when your code has _Ember.run_ and Ember executes the main _RunLoop_?**

Nothing weird. The operations in your **Ember.run** will be merged into the main _RunLoop_ allowing for normal operation.

**How are promises affected?**

If you use **Ember.RSVP** or a library that uses **RSVP.js** library to create a promise, you’ll have to wrap the creating code in `Ember.run`.

**What kind of operations have asynchronous side effects?**

- `Em.Object.set()`
- `Em.Object.create()`
- `Em.Object.destroy()`
- `Em.$.ajax()` ( and related functions )

**Examples**

_AJAX Requests_

```javascript
App.ProductsRoute = Ember.Route.extend({
  model: function() {
    var promise;
    Ember.run(function(){
      promise = Em.$.getJSON('products.json')
    });
    return promise;
  }
});

```

_Masonry Tiles_

```javascript
// source http://alexmatchneer.com/blog/ember_run_loop_talk/#/practical
App.MasonryView = Ember.CollectionView.extend({
  didInsertElement: function() {
    // At this point, no child elements have been rendered, so
    // schedule buildMasonry to run after the child elements
    // have rendered.
    Ember.run.scheduleOnce('afterRender', this, 'buildMasonry');
  },
  buildMasonry: function() {
    this.$().masonry();
  }
}); 

```

**What am I missing? What’s incorrect or could be clearer?**

---

<div class="post-metadata">

### Author: ![rwjblue](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/rwjblue/32/9411_2.png) [@rwjblue](https://discuss.emberjs.com/u/rwjblue)
#### Post date: [October 8, 2013, 8:33pm UTC](https://discuss.emberjs.com/t/guide-asynchronous-side-effects-in-testing/2905/2 "2013-10-08T20:33:51Z")

</div>

> [@tarasm](#):
>
> The RunLoop has 2 methods Ember.run.begin() and Ember.run.end() which are used to initialize and start the RunLoop, respectively.

This tripped me up a bit on my first read through. The naming seems odd, but it is definitely correct.

Quoting from the docs for [`Ember.run.begin`](http://emberjs.com/api/classes/Ember.run.html#method_begin):

> Begins a new RunLoop. Any deferred actions invoked after the begin will be buffered until you invoke a matching call to Ember.run.end(). This is a lower-level way to use a RunLoop instead of using Ember.run().

---

<div class="post-metadata">

### Author: ![rwjblue](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/rwjblue/32/9411_2.png) [@rwjblue](https://discuss.emberjs.com/u/rwjblue)
#### Post date: [October 8, 2013, 8:34pm UTC](https://discuss.emberjs.com/t/guide-asynchronous-side-effects-in-testing/2905/3 "2013-10-08T20:34:59Z")

</div>

@tarasm - I definitely agree that we need a guide on this. Thanks for spearheading the effort!

---

<div class="post-metadata">

### Author: ![tarasm](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/tarasm/32/15980_2.png) [@tarasm](https://discuss.emberjs.com/u/tarasm)
#### Post date: [October 8, 2013, 10:23pm UTC](https://discuss.emberjs.com/t/guide-asynchronous-side-effects-in-testing/2905/4 "2013-10-08T22:23:47Z")

</div>

@rwjblue the description in the docs is too technical. I broke that sentence into a few sentences. Let me know if its better.

---

<div class="post-metadata">

### Author: ![rwjblue](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/rwjblue/32/9411_2.png) [@rwjblue](https://discuss.emberjs.com/u/rwjblue)
#### Post date: [October 8, 2013, 10:35pm UTC](https://discuss.emberjs.com/t/guide-asynchronous-side-effects-in-testing/2905/5 "2013-10-08T22:35:33Z")

</div>

@tarasm - That definitely reads better.

---

<div class="post-metadata">

### Author: ![juarezpaf](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/juarezpaf/32/14940_2.png) [@juarezpaf](https://discuss.emberjs.com/u/juarezpaf)
#### Post date: [October 10, 2013, 9:46am UTC](https://discuss.emberjs.com/t/guide-asynchronous-side-effects-in-testing/2905/6 "2013-10-10T09:46:59Z")

</div>

Hey guys… I am using normal Em.$.ajax() in my app using return Em.$.ajax(…).then(), but I started to look some presentations and materials talking about RSVP and promises. What is the best way to ensure that multiples requests follow a sequence and the second request wait to start when the first request ends? Sometimes I need to do two or more dependents Ajax requests.

---

<div class="post-metadata">

### Author: ![SBoudrias](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/sboudrias/32/15175_2.png) [@SBoudrias](https://discuss.emberjs.com/u/SBoudrias)
#### Post date: [October 11, 2013, 6:39pm UTC](https://discuss.emberjs.com/t/guide-asynchronous-side-effects-in-testing/2905/7 "2013-10-11T18:39:49Z")

</div>

@tarasm Just to make sure I understand this correctly, in order to allow easier testing, you should wrap async operations in `Ember.run` in your normal code? (Not only on your test code?)

---

<div class="post-metadata">

### Author: ![Jun\_Andrew\_Hu](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/jun_andrew_hu/32/224_2.png) [@Jun\_Andrew\_Hu](https://discuss.emberjs.com/u/Jun_Andrew_Hu)
#### Post date: [October 11, 2013, 8:04pm UTC](https://discuss.emberjs.com/t/guide-asynchronous-side-effects-in-testing/2905/8 "2013-10-11T20:04:13Z")

</div>

Thanks @tarasm for spearheading this guide!

To me, this seems to imply that integration testing using Ember.test is very difficult to use, because it is not easy to enforce these many rules correctly. And it looks if you miss one thing, you just get that generic error message with little clue to understand where it is wrong …

---

<div class="post-metadata">

### Author: ![tarasm](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/tarasm/32/15980_2.png) [@tarasm](https://discuss.emberjs.com/u/tarasm)
#### Post date: [October 12, 2013, 6:31pm UTC](https://discuss.emberjs.com/t/guide-asynchronous-side-effects-in-testing/2905/9 "2013-10-12T18:31:54Z")

</div>

@SBoudrias If your goal is to write testable code, then you should be conscious of the asynchronous side effects that your code creates. Technically speaking, its usually sufficient to wrap your tests in Ember.run but stylistically speaking, I think its better to wrap your original code in Ember.run when your code introduces an async side effect. This is what Ember does internally.

I think its stylistically better because it forces you to be conscious async side effects that your code creates and serves as a future warning that this is happening.

---

<div class="post-metadata">

### Author: ![tarasm](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/tarasm/32/15980_2.png) [@tarasm](https://discuss.emberjs.com/u/tarasm)
#### Post date: [October 12, 2013, 6:33pm UTC](https://discuss.emberjs.com/t/guide-asynchronous-side-effects-in-testing/2905/10 "2013-10-12T18:33:48Z")

</div>

@Jun_Andrew_Hu I don’t make any comment about difficulty of integration testing with Ember. I’m just trying to help people deal with this message.

---

<div class="post-metadata">

### Author: ![pwagenet](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/pwagenet/32/14172_2.png) [@pwagenet](https://discuss.emberjs.com/u/pwagenet)
#### Post date: [October 22, 2013, 2:33am UTC](https://discuss.emberjs.com/t/guide-asynchronous-side-effects-in-testing/2905/11 "2013-10-22T02:33:14Z")

</div>

In general, all Ember code should happen within a run loop except for the Application initialization. When working from within Ember, this will happen automatically. However, when you run Ember code from a callback in another library, you need to manually wrap it in a run loop. To make things a bit easier on people who are messing around in the console, we’ve introduced the concept of an autorun which automatically generates a run loop if you’re missing one. However, the performance of this isn’t great and it can behave unpredictably in tests. This is why you’ll get a warning about missing run loops in your tests.

---

<div class="post-metadata">

### Author: ![kamrenz](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/kamrenz/32/4992_2.png) [@kamrenz](https://discuss.emberjs.com/u/kamrenz)
#### Post date: [November 19, 2013, 1:54pm UTC](https://discuss.emberjs.com/t/guide-asynchronous-side-effects-in-testing/2905/12 "2013-11-19T13:54:29Z")

</div>

@tarasm Let’s say you wanted to write a test to check the Ajax request for App.ProductsRoute. Can you give an example of what your test look like using Ember’s “visit”?

---

<div class="post-metadata">

### Author: ![tarasm](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/tarasm/32/15980_2.png) [@tarasm](https://discuss.emberjs.com/u/tarasm)
#### Post date: [November 19, 2013, 2:43pm UTC](https://discuss.emberjs.com/t/guide-asynchronous-side-effects-in-testing/2905/13 "2013-11-19T14:43:12Z")

</div>

This is something that took me some time to understand but not advisable to test your application this way. You would be much better off to split testing of the UI from testing your backend. In this scenario, you would use mock data or stub the API methods.

---

<div class="post-metadata">

### Author: ![kamrenz](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/kamrenz/32/4992_2.png) [@kamrenz](https://discuss.emberjs.com/u/kamrenz)
#### Post date: [November 19, 2013, 3:15pm UTC](https://discuss.emberjs.com/t/guide-asynchronous-side-effects-in-testing/2905/14 "2013-11-19T15:15:23Z")

</div>

@tarasm I seem to agree. I can’t for the life of me get rid of “Assertion failed: You have turned on testing mode, which disabled the run-loop’s autorun. You will need to wrap any code with asynchronous side-effects in an Ember.run” when I try to do a complete integration from front-end test to back-end data. Even if I wrap the route’s model hook Ajax call with an Ember.run like you have above. Of course, my tests work fine with stubbed data, but that switch to an async test and the $.getJSON seems to make this non-testsable. Isn’t this something people normally test for in their applications?

Test

```
asyncTest("Verify a route", function() {
	visit("/route_to_verify").then( function() {
		ok( /* something that is ok */ );
		start();
	});
});

```

Router

```
App.MerchandiseIndexRoute = Em.Route.extend({
	model: function() {
		var promise;
		Em.run(this, function() {
			promise = Em.$.getJSON("/url/im/gonna/get/json/from");
		});
		return promise;
	}
});

```

---

<div class="post-metadata">

### Author: ![tarasm](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/tarasm/32/15980_2.png) [@tarasm](https://discuss.emberjs.com/u/tarasm)
#### Post date: [November 22, 2013, 2:13am UTC](https://discuss.emberjs.com/t/guide-asynchronous-side-effects-in-testing/2905/15 "2013-11-22T02:13:32Z")

</div>

@kamrenz your problem is with what happens after your response is returned. Your promise is resolved without a run loop and you get that error. You shouldn’t need to use asyncTest here.

```javascript
App.MerchandiseIndexRoute = Em.Route.extend({
	model: function() {
		return Em.$.getJSON("/url/im/gonna/get/json/from").then(function(result){
                   Em.run(function(){
                       // do whatever you gotta do with processing the response
                   });
                   return result;
                ], function(error){
                   /** don't forget to handle the error */
                ]);
	}
});

```

---

<div class="post-metadata">

### Author: ![kamrenz](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/kamrenz/32/4992_2.png) [@kamrenz](https://discuss.emberjs.com/u/kamrenz)
#### Post date: [November 26, 2013, 1:35pm UTC](https://discuss.emberjs.com/t/guide-asynchronous-side-effects-in-testing/2905/16 "2013-11-26T13:35:15Z")

</div>

@tarasm I switched my test code to the following:

```
test("Verify a route", function() {
visit("/route_to_verify").then( function() {
	ok( /* something that is ok */ );
});

```

});

And I changed my Index Route up to what you have and I am still getting the same error about needing to "wrap any code with asynchronous side-effects in an Ember.run.

```
App.MerchandiseIndexRoute = Em.Route.extend({
  model: function() {
    return Em.$.getJSON("/url/im/gonna/get/json/from").then(
      function(result) {
            Em.run(function(){
                   // do whatever you gotta do with processing the response
                   console.log("success");
            });
               return result;
            }, function(error) {
               /** don't forget to handle the error */
                 console.log("error");
        });
    }
});

```

---

<div class="post-metadata">

### Author: ![tarasm](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/tarasm/32/15980_2.png) [@tarasm](https://discuss.emberjs.com/u/tarasm)
#### Post date: [November 27, 2013, 12:11am UTC](https://discuss.emberjs.com/t/guide-asynchronous-side-effects-in-testing/2905/17 "2013-11-27T00:11:39Z")

</div>

@kamrenz Can you make a JSBin or show more of your code?

BTW, there was a library released today that’s designed to replace $.getJSON and makes this process a lot easier [https://github.com/instructure/ic-ajax](https://github.com/instructure/ic-ajax)

---

<div class="post-metadata">

### Author: ![kamrenz](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/kamrenz/32/4992_2.png) [@kamrenz](https://discuss.emberjs.com/u/kamrenz)
#### Post date: [November 27, 2013, 9:19pm UTC](https://discuss.emberjs.com/t/guide-asynchronous-side-effects-in-testing/2905/18 "2013-11-27T21:19:40Z")

</div>

Thanks @tarasm the ic-ajax $.getJSON drop-in replacement fixed the testing. There are no Ember.run() implementations needed. I can simply return my ajax model data. You are also correct that I don’t need an asyncTest. Thanks for the help!

---

<div class="post-metadata">

### Author: ![tarasm](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.emberjs.com/tarasm/32/15980_2.png) [@tarasm](https://discuss.emberjs.com/u/tarasm)
#### Post date: [November 27, 2013, 9:20pm UTC](https://discuss.emberjs.com/t/guide-asynchronous-side-effects-in-testing/2905/19 "2013-11-27T21:20:49Z")

</div>

You’re welcome. Glad you got it figured out.

---

<div class="post-metadata">

### Author: ![pkenway](https://avatars.discourse-cdn.com/v4/letter/p/91b2a8/32.png) [@pkenway](https://discuss.emberjs.com/u/pkenway)
#### Post date: [September 23, 2014, 7:22pm UTC](https://discuss.emberjs.com/t/guide-asynchronous-side-effects-in-testing/2905/20 "2014-09-23T19:22:47Z")

</div>

I’m having a somewhat similar issue here. Our site has a timer that runs on a setInterval within the Ember code. Initially I was getting the same error as in the original post. Once I figured out the source of the problem and wrapped the callback in Ember.run, the error went away, but Qunit never seems to register that the page is idle, and my next “andThen” function is never called. I assume that it’s waiting for the runloop to be empty for some given period of time before it considers the page loaded. Is there any way around this?

[Next page](https://discuss.emberjs.com/t/guide-asynchronous-side-effects-in-testing/2905.md?page=2)
