How to use JestJS with a database? - express

I am working on a new project using Jest, Express and Sequelize to create an API.
I have some endpoints working, and am writing tests for each of my endpoints.
Coming from the Ruby on Rails world, I am used to writing tests where the database is cleaned between every test.
This seems to be impossible in Jest because there does not appear to be a way to not have tests clobber the database since they are all running in parallel
With that in mind, I created this global beforeAll function in tests/support/setup.js and configured Jest to use this method before all my specs run:
// package.json
{...
"jest": {
"setupFilesAfterEnv": [
"<rootDir>/tests/support/setup.js"
]
}
}
// tests/support/setup.js
import models from '../../db/models'
global.beforeAll(async () => {
await models.sequelize.drop()
await models.sequelize.sync()
})
But it looks like this doesn't work either, but I think this is actually running the beforeAll method before each test suite....so the database still gets clobbered.
Right now, Jest seems useless to me when used with a database. Am I missing something?
What are some methods for using Jest with a database where each test is run with a pristine database?

Related

jest error: const warnedKeys: {[string]: boolean} = {};

If I run yarn test, which runs jest, I get the following error:
C:\react-native-project\node_modules\react-native\Libraries\Utilities\warnOnce.js:15
const warnedKeys: {[string]: boolean} = {};
But that only happens if I follow the directions of the react-native-testing-library:
Then automatically to add it to your jest tests by using setupFilesAfterEnv option in the
jest.config.js file:
If I remove the file I will not get that error and I can get simple tests to run. When I remove the file, the test runs but AsyncStorage is not recognized so the tests still don't run. I have AsyncStorage. It's installed and the app works, but I want to add component tests. I also noticed the file, jest.config.js, is conspicuously missing from the testing project itself. Is there any documentation or working example? I would rather not do a diff of my project and the testing project. Is there a more well-documented or reliable testing framework/module available?
I'm able to get working tests by following the documentation of the React Native Testing Library with the npm package name of #testing-library/react-native not to be confused with the React Native Testing Library with the npm package name of react-native-testing-library. Both packages allow testing components and are recommended by React-Native documentation but this one works when following the instructions. It also has instructions "to define a custom render method that includes things like global context providers, data stores, etc" so that testing components with AsyncStorage and such shouldn't be a problem.

How to Manage Staging and Production Environments in a React Native App

I got a react-native app already ready and works but the app points on a prod api so to avoid problems I wanted that she points on a rest api, so how can I reconfigure it, I have only an environment file.js that contains the URL api, and this file is called in the API service
I tried react-native config but didn't know how to make it work,
All I want is to duplicate that env file because he contains all necessary URLs, so I want to have file named envProd and another named envStaging they should be similar the only different part is the URL of my api , so when I want to run the app i precise which file I want to choose to run with
If the API URL's are the only difference, you don't need to create two separate config files. Instead, you can make use of the inbuild __DEV__ global variable in JavaScript to determine if you're using React Native packager (dev mode) or not (production).
Ref: https://facebook.github.io/react-native/docs/javascript-environment.html
So, something like below.
var apiURL = __DEV__ == true ? 'development.api.com' : 'prod.api.com';
I am finding switching environments quite hard to manage.
__DEV__ is awesome for local disabling stuff when in development. Won't work for any of the builds though.
For staging vs production seems that configuring react-native-config is the best. Unfortunately, next to being somewhat hard to configure binaries need to get recompiled separately for each environment. This means - one update - two build with uploads to whatever provider you use. It can get more complex if you use something like codepush too.
possible solution
Create a hidden feature in your app that allows to toggle the environment from the within the app. This way you can have one build, give it to testers. They switch env to staging and later you only need to promote it as a production build.
This could be something like tap 10 times on an empty space somewhere - the more creative you get the better :)
Good luck
const _Environments = {
production: {
API_BASE: 'https://api.test.com/',
USERNAME: 'admin',
PASSWORD: '1234',
},
development: {
API_BASE: 'https://dev.api.test.com/',
USERNAME: 'admin',
PASSWORD: '1234',
},
};
function getEnvironment() {
// Insert logic here to get the current platform (e.g. staging, production, etc)
var platform = __DEV__ ? 'development' : 'production';
// ...now return the correct environment
return _Environments[platform];
}
export const Environment = getEnvironment();
Try this. using yargs you can replace static import content with dynamic scripts.

async-storage SyntaxError Unexpected identifier while transpiling with Babel7

After using #react-native-community/async-storage and transpile it with the following npm command in my react-native environment.
"test": "NODE_ENV=test ./node_modules/.bin/mocha --timeout 5000 --require #babel/register \"./src/shared/__tests__/**/*.spec.js\""
I did some research and in no vain. But I found it happens to Jest too.
jest test fails after installing react-native-async-storage
this is my babel.config.js
module.exports = {
env: {
production: {
},
test: {
presets: [
'#babel/preset-env'
],
},
},
};
I'm only testing non-jsx code only so #babel/preset-env seems to be working alright.
node_modules/#react-native-community/async-storage/lib/index.js:5
import AsyncStorage from './AsyncStorage';
^^^^^^^^^^^^
SyntaxError: Unexpected identifier
It seems like no one likes to answer jest newbie questions....
anyway, when starting to learn jest, I encountered some funny error messages that doesn't reflect the actual error. There are some possible situations a developer can consider.
You didn't to mock your module say A_module that is inside node_modules so one of the modules say B_modules inside A_modules uses a NativeModules from react so Jest cannot performa a test. Please look at stack trace or use a debugger to find out which one you prefer to mock.
Mock a module that uses NativeModules (similar to point 1, but more direct and concise )
You need to understand jest more thoroughly before you proceed. Reading documentation is good but jump to example when you think fit. especially check out the examples that you really need and read related ones. Many of the time, either your Babel setting or mocking methods is incorrect.
use jest.mock instead of jest.genMockFromModule. Why? there are some functions or init function that causes your test to crash at this statement. Because it calls NativeModules or something jest doesn't allow. use mock instead.
Solutions to this question: please refer to this most updated solution.
thanks

Ember.js testing component with service dependency

I'm trying to write tests for my addon, but encountering some weird behaviour.
I have created a service (via ember-cli generate), which is used inside a component.
When an actual application is running everything is working fine.
However, when testing the component I get an error saying that the service is undefined when trying to access any of its properties/methods.
In the test i've put the service in "needs" like so:
needs: ['service:my-service']
"Needing" other components (e.g. child ones used inside) works as expected, services strangely fail.
Are there any additional steps that need to be done?
Running ember-cli 0.1.12.
When you generate a service, it also generates an initializer whose job it is to inject the service into the various places that you need it.
So, when you run acceptance tests your app will have booted and initializers will have been run, therefore the services will be available.
However, when unit testing components you get a clean container (better for testing). You just need to inject what you need:
moduleForComponent('foo-bar', null, {
setup: function(container) {
container.register('service:foo', FooService);
container.injection('component', 'fooService', 'service:foo');
}
});
I managed to get this working by using the new Ember.inject API available in the latest (as of writing) 1.10 release.
Apparently the new inject API is intended to replace needs in the future, it also works great with unit tests.
We just managed to get one working using needs: ['service:myService'] instead of needs: ['service:my-service'].

E2E Testing for AngularJS App on another computer

I'm developing single page application on AngularJS for learning. My project is located on Apache HTTP Server on another computer, I use WinSCP synchronisation while developing so that it is always the last version of my work.
Halfway through (actually, when I has already finished the biggest part the application), I realized that I don't have any tests and I should learn how to test what I do not just manually. I decided to try writing E2E tests for my AngularJS application using Karma Test Runner.
I installed Karma via npm, initialized it (karma init test/karma.conf.js), but what happens now?
I tried karma start test/karma.conf.js it launches Chrome (as I stated in config) and says that
Karma - connected
Chrome 26.0 (Windows) is idle
even though in conf file there are specified my test file:
files = [
'test/first_test.js'
];
And that's what inside it:
describe('my app', function() {
browser().navigateTo('/');
it('should then be.', function() {
expect(browser().location().url()).toBe('/login');
});
});
Thanks in advance!
EDIT: I realized, it's not just 'Chrome is idle', there's also console log error:
Uncaught ReferenceError: browser is not defined
Any ideas? I'm so confused right now.
Browser is only defined inside of beforeEach. Try this:
describe('my app', function() {
beforeEach(function(){
browser().navigateTo('/');
});
it('should then be.', function() {
expect(browser().location().url()).toBe('/login');
});
});
Alright, looks like I solved it myself.
I should have added
ANGULAR_SCENARIO,
ANGULAR_SCENARIO_ADAPTER,
to the files property of karma config file. After that, I progressed a little bit, but still got a lot of troubles, but essentially the main was that I got error that resumeBootstrap was undefined. My app was using AngularJS 1.0.4, but it looks like Karma's Adapters are for 1.0.6+ only. Upgrading app to 1.0.6 helped with resumeBootstrap.
Regarding testing the app on external server:
proxies = {
'/': 'http://another.internal/app/'
};
and don't forget to change links to CSS and JS files in app's index.html from local (css/style.css) to web (//another.internal/app/css/style.css).