ember-cli-mirage: Does not play nicely with rfc232/rfc268 tests
The new test framework (rfc232/rfc268) runs initializers differently than the older moduleFor* tests, and is problematic for how ember-cli-mirage sets itself up. Specifically, it can cause the multiple pretender instances warning, and can leak state between tests.
Old tests
In the old tests, each individual test would have its own mirage server instance.
integration & unit
In old-style integration/unit tests, the test framework would not run any initializers, so the test itself would have to invoke the initializer and shut down the server manually.
acceptance
In old-style acceptance tests, initializers would run before each test, so ember-cli-mirage’s initializer would run before each test, and its blueprint would cause the server to be shut down after each test.
New tests
There are no longer any relevant-to-this-issue distinctions between the various types of tests – they all behave the same with respect to initializers. That behavior is that, while instance initializers run before each test, initializers just run before the first test in the entire test run. destroy-app.js is no longer used, so ember-cli-mirage’s current blueprint has no effect on these tests. This causes a couple of problems:
- If you have a mix of old and new-style tests, you’ll probably get a whole bunch of multiple pretender instance warnings since the first new-style test that runs will create a mirage server instance and never shut it down, so every old-style test that sets its own up (either via the initializer called from a
moduleForAcceptancetest or manually in a unit/integration test) will create a “second” pretender instance. - If all of your tests are new-style tests, changes to the mirage database and routes dynamically created in one test will persist into other tests because it’s one long-lived instance that is never shut down.
Possible solutions
- Change the server from being a standalone object to a singleton (
service:mirage?) registered in, and created out of, the container. This will ensure that it is shut down when the application is shut down. Then change the initializer that creates it to be an instance initializer. That way it will be created before each test, and shut down after each test like it used to be. This would have the side benefit of allowing users like myself that aren’t fond of globals to access the server by just looking it up in the container (but it could still set itself as a global to preserve compatibility). - Implement some mechanism for resetting the mirage server to its initial state and implement an instance initializer that does that.
- Explore other ways of running code after each test to shut down/reset the mirage server. This could be blueprint code that detects QUnit vs Mocha and adds global after-test behavior to them, or some other mechanism that I’m not aware of, or that would have to be implemented in
@ember/test-helpers. This also might involve changing the existing initializer to an instance initializer.
My strong preference is (1), but I don’t know the history of how the mirage setup code came to be how it is today, so maybe there are reasons to not make it a container object?
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 9
- Comments: 15 (2 by maintainers)
Commits related to this issue
- Support rfc232/rfc268 tests Implement `setupMirageTest()` that can be called in rfc232/rfc268 tests to start mirage and set it as `this.server`. Also implement an instance initializer that, if the `e... — committed to bendemboski/ember-cli-mirage by bendemboski 6 years ago
- Support rfc232/rfc268 tests Implement `setupMirageTest()` that can be called in rfc232/rfc268 tests to start mirage and set it as `this.server`. Also implement an instance initializer that, if the `e... — committed to bendemboski/ember-cli-mirage by bendemboski 6 years ago
- Support rfc232/rfc268 tests Implement `setupMirageTest()` that can be called in rfc232/rfc268 tests to start mirage and set it as `this.server`. Also implement an instance initializer that, if the `e... — committed to bendemboski/ember-cli-mirage by bendemboski 6 years ago
- Support rfc232/rfc268 tests Implement `setupMirageTest()` that can be called in rfc232/rfc268 tests to start mirage and set it as `this.server`. Also implement an instance initializer that, if the `e... — committed to bendemboski/ember-cli-mirage by bendemboski 6 years ago
FWIW this is what we’re doing in some projects that use pretender directly instead of mirage. I’m assuming mirage could provide a similar
setupMirage()function that sets up and tears down the server correctly.I’ve used the same workaround as @Turbo87 suggested. First, I disable Mirage globally in environment.js, then I have a setup method:
Then I use it as:
FWIW I worked around this issue by implementing an instance initializer that looks like this:
@ajcolter
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';