I am quite new to ember.js project where i am trying to write my first acceptance test for testing my root path works. I am following the below tutorial . I was unable to import "module-for-acceptance" from the helpers as its deprecated. when i run the below test i am getting an error which says (0 , _testHelpers.andThen) is not a function. I had also gone through ember js discussion post and imported andThen. It does not seem to work . How can i import andThen and make my test work . Thank you.
Test case
import { module, test } from 'qunit';
import { visit, currentURL ,andThen } from '#ember/test-helpers';
import { setupApplicationTest } from 'ember-qunit';
module('Acceptance | list rentals', function(hooks) {
setupApplicationTest(hooks);
test('should redirect to rentals route', function (assert) {
visit('/');
andThen(function() {
assert.equal(currentURL(), '/rentals', 'should redirect automatically');
});
});
});
Log
Died on test #1 at Object.<anonymous> (http://localhost:7357/assets/tests.js:8:21)
at processModule (http://localhost:7357/assets/test-support.js:3765:16)
at module$1 (http://localhost:7357/assets/test-support.js:3790:4)
at Module.callback (http://localhost:7357/assets/tests.js:6:21)
at Module.exports (http://localhost:7357/assets/vendor.js:111:32)
at requireModule (http://localhost:7357/assets/vendor.js:32:18)
at TestLoader.require (http://localhost:7357/assets/test-support.js:13736:9): (0 , _testHelpers.andThen) is not a function# 60 ms
Source:
TypeError: (0 , _testHelpers.andThen) is not a function
at Object.<anonymous> (http://localhost:7357/assets/tests.js:10:32)
at runTest (http://localhost:7357/assets/test-support.js:5618:30)
at Test.run (http://localhost:7357/assets/test-support.js:5604:6)
at http://localhost:7357/assets/test-support.js:5831:12
at processTaskQueue (http://localhost:7357/assets/test-support.js:5197:24)
at advanceTaskQueue (http://localhost:7357/assets/test-support.js:5182:4)
at Object.advance (http://localhost:7357/assets/test-support.js:5168:4)
at unblockAndAdvanceQueue (http://localhost:7357/assets/test-support.js:6944:20)
at begin (http://localhost:7357/assets/test-support.js:6978:5)
at http://localhost:7357/assets/test-support.js:6219:6
Tried to restart test while already started (test's semaphore was 0 already)# 61 ms
Source:
at resume (http://localhost:7357/assets/test-support.js:6171:5)
at done (http://localhost:7357/assets/test-support.js:6362:7)
at Class.asyncEnd (http://localhost:7357/assets/test-support.js:13822:9)
at asyncEnd (http://localhost:7357/assets/vendor.js:68040:15)
at http://localhost:7357/assets/vendor.js:67197:31
at invoke (http://localhost:7357/assets/vendor.js:65509:16)
at Queue.flush (http://localhost:7357/assets/vendor.js:65400:13)
at DeferredActionQueues.flush (http://localhost:7357/assets/vendor.js:65597:21)
Ember testing has moved to an async/await pattern instead of using andThen and other global test helpers. That tutorial is for a fairly old version of Ember, you'll have a lot more success with a more recent guide. Even if you are not ready to update to a newer version of ember I would still recommend following the new test patterns as they are significantly easier to read and write.
If you want to test it with andThen you wouldn't need to import it as it was provided as a global, but you need to make sure your testing dependencies are correct. I would start with comparing your current package.json with the default for ember apps at that time you may need to downgrade some packages in order to get access to the old imports and global test helpers.
Related
I am trying to create an extension off jest-node-environment as a CustomTestEnvironment but am getting the following error when trying to run jest
● Test suite failed to run
~/git/my-application/tests/environment/custom-test-environment.ts:1
import NodeEnvironment from 'jest-environment-node';
^^^^^^
SyntaxError: Cannot use import statement outside a module
at runTestInternal (../node_modules/jest-runner/build/runTest.js:226:5)
I believe this error means it doesn't recognize this as a typescript file, and hasn't transpiled it. ( I am using the latest version of jest 26.0.1)
Based on discussions in the jest github, the PR to make this work was slated for Jest 26 but was pulled from Jest 26 and is (hopefully) going to be in Jest 27.
https://github.com/facebook/jest/pull/8751
That being said, I've seen samples of people doing it this way online but for me I'm not having any luck following their lead.
import NodeEnvironment from "jest-environment-node";
import {LocalObject} from "./object/local-object.helper";
export class CustomTestEnvironment extends NodeEnvironment {
public async setup(): Promise<void> {
await super.setup();
this.global.localObject = LocalObject.init()
}
public async teardown(): Promise<void> {
LocalObject.teardown(this.global.localObject)
await super.teardown();
}
}
The LocalObject is just a thin wrapper around a test utility which has a complex startup and teardown and which I want to provide to tests to be able to publish test data and kick off the component test.
If I change the imports to be require -
const NodeEnvironment = require("jest-environment-node");
const {LocalObject} = require("./object/local-object.helper");
Then I get this error instead -
SyntaxError: Unexpected token 'export'
If I move the export into an module.exports then I get the following error
public async setup(): Promise<void> {
^^^^^
SyntaxError: Unexpected token 'async'
Seems to me like it's not treating this file as typescript.
Is there any workaround to be able to use this as a typescript file? The LocalObject is written in typescript, so I believe that I need this to be typescript to work right with that one, and it is important that LocalObject file remains typescript for test files to use it correctly.
Alternative question:
Can I do the same kind of setup/teardown logic in the setupFilesAfterEnv I only saw that they were run before, but not after tests. Thanks.
UPDATE: Jest 27 is now released and now supports this. If you are using an older version of Jest, update to Jest 27 to be able to use CustomEnvironment as typescript https://jestjs.io/blog/2021/05/25/jest-27#features-coming-with-breaking-changes
Modules used in the following configuration options are now transformed like the rest of your code, which may be breaking if you relied on them being loaded as-is:
testEnvironment
runner
testRunner
snapshotResolver
Alternatively, you can continue to use the workaround below for prior versions.
This isn't supported in Jest 26 and is slated to be in Jest 27 https://github.com/facebook/jest/pull/8751#issuecomment-699049851
For now the solution is to use setupFilesAfterEnv files in my jest.config https://jestjs.io/docs/en/configuration#setupfilesafterenv-array.
From there I could put all my my setup/teardown in beforeAll() and afterAll() blocks. This was effectively equivalent to using the Node Environment and the setupFilesAfterEnv files is compatible with typescript.
//jest.setup.ts
import {LocalObject} from "./object/local-object.helper";
let localObject: LocalObject;
beforeAll(async () => {
//Start my environment or seed data to DB or whatever
localObject = await LocalObject.init()
}
afterAll(async () => {
//teardown or clean things started in setup my environment
await localObject.teardown()
}
Due to the build process I'm using to push my app out I'm passing some environment variables in a file after build, which works fine. However it breaks my tests with the following error message:
TypeError: Cannot read property 'DATA' of undefined
57 | Auth: {
58 | oth,
> 59 |
| ^
60 |
61 | identity: checkEnv(window.env.DATA,
62 | process.env.REACT_APP_DATA),
I've tried many solutions but have yet to be able to mock the window.env data, how would I do so?
Create React App allows you to initialize the test environment by including a src/setupTests.js file that "will be automatically executed before running your tests".
Create React App also sets up the testing environment with jsdom which provides the global window object.
You can set window.env in src/setupTests.js and it will be available during your tests:
src/setupTests.js
window.env = {
DATA: 'hi'
}
src/code.js
export const getData = () => window.env.DATA
src/code.test.js
import { getData } from './code';
test('env', () => {
expect(getData()).toBe('hi'); // SUCCESS
})
Brian Adams's (also Bryan Adams has great songs!) answer is correct but I wanted to clarify some things. In my case, I tried multiple things but none worked, including Brian's solution. I created the src/setupTests.js file but it seemed like it was not doing anything. After spending hours I realized that I was using react version 17.0.2 and enzyme-adapter version 16.x.x. That was the reason why none of the solutions were working. After installing "#wojtekmaj/enzyme-adapter-react-17" everything started working fine. Settings inside setupTests.js file are automatically applied during the test. So if the solutions that you are trying are not working, make sure that you are using the correct versions of the packages.
I am using Jest for my unit tests and I'm in the process of integrating Cucumber.js for running specs written in Gherkin.
I have it all set up and it's working, but I am running into one problem: How can I use Jest's expect? I could use chai's, but I'd like to keep the expect syntax the same between my unit tests and my step definitions (I don't want to.equal in my step definitions and toEqual in my unit tests).
How can I do that? After some digging it seems as if Jest relies on the expect npm package. I could depend on that package explicitly in my package.json, but I'd much rather use my existing Jest dependency. Maybe that's not possible, but I hope it is.
Another option would be to somehow execute the Gherkin specs with the Jest test-runner. I'd be open to that option as well. At the moment I'm running them by calling cucumber.js separately from my Jest test-runner.
My react-native environment:
"cucumber": "^4.1.0",
"jest": "22.4.2",
In my steps definition file, I just require it like this
const { Given, Then, When } = require('cucumber');
const expect = require('expect');
Expect is part of Jest, so you can import it as its own object. Then I can use it wherever I need an assertion. Note: newMember is declared and populated elsewhere.
Given('Sara has provided account details', function() {
for (const prop in newMember) {
expect(newMember[prop]).toBeTruthy();
}
});
Hope that helps.
expect is a globally scoped during jest runtime. So as long as you are running jest it will be available. I'm using this package (needs some config to transform correctly to your babel config): gherkin-jest
Here's a feature using the DOM-testing example from the jest docs:
Feature: Using feature files in jest and cucumber
As a developer
I want to write tests in cucumber and jest
So that businesspeople understand tests and I can test React
Scenario: Emoji toggles upon checking and unchecking the checkbox
Given I did not check the checkbox, so the label is "😭"
When I check the box and the emoji toggles to be "😎"
import {cucumber as c} from 'gherkin-jest'
import React from 'react'
import {mount} from 'enzyme'
import {Checkbox} from '../src/components'
c.defineCreateWorld(() => ({
checkbox:null
}))
c.defineRule('I did not check the checkbox so the label is {string}', (world, off) => {
world.checkbox = mount(<Checkbox labelOff={off} />)
expect(world.checkbox.text()).toBe(off)
})
c.defineRule('I checked the box and the emoji toggles to be {string}', (world, on) =>{
world.checkbox = mount(<Checkbox labelOn={on}/>)
world.checkbox.find('TouchableOpacity').props().onPress()
expect(world.checkbox.text()).toBe(on)
})
This issue I posted gives an example of the config.
An alternative would be to use jest-cucumber
https://www.npmjs.com/package/jest-cucumber.
gives you the flexibility of using both frameworks
I'm currently trying to add Jest tests to a React application (found here).
However, when I run the following test,
/** #jsx React.DOM */
jest.dontMock('jquery');
jest.dontMock('../js/components/CategoryPage.jsx');
describe('Category Page', function() {
var React = require('react/addons');
var TestUtils = React.addons.TestUtils;
var CategoryPage = require('../js/components/CategoryPage.jsx');
it('renders into the page correctly', function() {
// Render the CategoryPage into the document
var categoryPage = TestUtils.renderIntoDocument(
<CategoryPage params={{"category": "tests"}} />
);
expect(categoryPage).toBeDefined();
});
});
I get the following error:
● Category Page › it renders into the page correctly
- TypeError: Property 'makeHref' of object #<Object> is not a function
at Navigation.makeHref (/home/stephen/reps/node_modules/react- router/modules/mixins/Navigation.js:29:25)
at React.createClass.getHref (/home/stephen/reps/node_modules/react-router/modules/components/Link.js:76:17)
at React.createClass.render (/home/stephen/reps/node_modules/react-router/modules/components/Link.js:97:18)
at ReactCompositeComponentMixin._renderValidatedComponent (/home/stephen/reps/node_modules/react/lib/ReactCompositeComponent.js:1260:34)
at wrapper [as _renderValidatedComponent] (/home/stephen/reps/node_modules/react/lib/ReactPerf.js:50:21)
at ReactCompositeComponentMixin.mountComponent (/home/stephen/reps/node_modules/react/lib/ReactCompositeComponent.js:802:14)
at wrapper [as mountComponent] (/home/stephen/reps/node_modules/react/lib/ReactPerf.js:50:21)
at ReactDOMComponent.ReactMultiChild.Mixin.mountChildren (/home/stephen/reps/node_modules/react/lib/ReactMultiChild.js:195:42)
at ReactDOMComponent.Mixin._createContentMarkup (/home/stephen/reps/node_modules/react/lib/ReactDOMComponent.js:260:32)
at ReactDOMComponent.Mixin.mountComponent (/home/stephen/reps/node_modules/react/lib/ReactDOMComponent.js:182:14)
at ReactDOMComponent.wrapper [as mountComponent] (/home/stephen/reps/node_modules/react/lib/ReactPerf.js:50:21)
at ReactDOMComponent.ReactMultiChild.Mixin.mountChildren (/home/stephen/reps/node_modules/react/lib/ReactMultiChild.js:195:42)
at ReactDOMComponent.Mixin._createContentMarkup (/home/stephen/reps/node_modules/react/lib/ReactDOMComponent.js:260:32)
Both my app and the CategoryPage component specifically use react-router. The CategoryPage contains a mixin which uses react-router for authentication. Based on my own debugging, I have found that the error is occurring when Jest tries to call makeHref, one of react-router's built-in methods for Navigation.
To fix this, I first tried calling jest.dontMock('react-router'), but this did not have any effect. The problem seems to be that, by not mocking CategoryPage, jest will automatically and irreversibly include all of its dependecies, unmocked.
Part of the reason this issue is so difficult to solve is because most people using Jest with React seem to not be testing their components, either because they are not as test-focused or because they are using Flux and only testing Stores, Dispatchers, etc. We are not yet using Flux, so this is not an option for us, but may be something we have to transition to in the future.
EDIT 1: The test passes if I remove the jest.dontMock('../js/components/CategoryPage.jsx') but then it is impossible to actually test the functionality of that component.
EDIT 2: When I exclude jest.dontMock('jquery') I get another error related to the mixin I use to create Modals:
Category Page › it encountered a declaration exception
- TypeError:
/home/stephen/reps/js/components/CategoryPage.jsx:
/home/stephen/reps/js/components/Feed.jsx:
/home/stephen/reps/js/components/InvestmentButton.jsx:
/home/stephen/reps/js/components/Modal.jsx:
/home/stephen/reps/js/mixins/BootstrapModalMixin.jsx:
/home/stephen/reps/node_modules/bootstrap/dist/js/npm.js:
/home/stephen/reps/node_modules/bootstrap/js/alert.js: Cannot call method 'on' of undefined
EDIT 3: I have seemingly isolated the bug to react-router's Navigation mixin, where it calls this.context.makeHref. The React team has deprecated this.context since version .9 so I believe this may be the source of the problems. Thus, any work-around or fix for this.context is welcome.
I went ahead and put together a fix which allows you to still use Jest.
https://labs.chie.do/jest-testing-with-react-router/
I ended up figuring this out with some help from the creator of rackt-router after creating the issue found here: https://github.com/rackt/react-router/issues/465 .
I got around this by using Karma and Jasmine to test my application. I then used the stub function makeStubbedDescriptor found here: https://gist.github.com/rpflorence/1f72da0cd9e507ebec29.
I am using QUnit to test my typescript code and everything is fine when I run a simple example like this: http://thomasardal.com/testing-typescript-with-typescript-using-qunit-and-chutzpah/
But my nightmare start when I try create unit tests for my SPA app.
At the moment to run the testing using Chutzpah on my VS I got a strange error:
"Can't Find variable home in mypath\home.tests.ts(line6).
My Code bellow:
home.ts
import logger = module('services/logger');
export var title = 'Home View';
export function activate() {
logger.log('Home View Activated', null, 'home', true);
return true;
}
home.tests.ts
/// <reference path="../../Scripts/qunit.d.ts" />
QUnit.module("home.ts tests");
import home = module("home");
test("test title from home viewmodel", function () {
// Calling to active public function from home viewmodel. (home.ts)
var activateResult:string = home.title;
// Assert
equal(activateResult, "Home View", "Result should be Home View ");
});
here you are my typeScript settings:
any idea what is wrong with my code?
UPDATE 1
The complete message from output windows in Vs2012 is:
Test 'home.ts tests:test activate function from home viewmodel' failed
Died on test #1 at file:///C:/Users/rolando/AppData/Local/Microsoft/VisualStudio/11.0/Extensions/kyo4ap1e.tvo/TestFiles/QUnit/qunit.js:412
at file:///D:/Mercatus/SourceCode/KILN/AquaVet2/SW/AquaVet.Web/App/viewmodels/_Chutzpah.7.home.tests.js:6: Can't find variable: home
in D:\Mercatus\SourceCode\KILN\AquaVet2\SW\AquaVet.Web\App\viewmodels\home.tests.ts (line 6)
0 passed, 1 failed, 1 total (chutzpah).
UPDATE 2
As you see in the code i am trying load home.ts using the keyword module("home").... I am not sure if that could be the reason of my problems. A better solution could be add a internal reference to home.ts
but i don't know how I can reference to activate function !!.
Just adding an import statement doesn't include an AMD module - you need a loader such as require.js to do that.
A bit of Googling throws up this https://github.com/jrburke/requirejs/wiki/Test-frameworks which may help you get QUnit working with async modules.
And this discussion about using Chutzpah with Require, which links to this example.