I'm trying to figure out how to test React Native (not React JS) components. Even looking at React Native's starter code, its difficult to see how to test it.
var AwesomeProject = React.createClass({
render: function() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Welcome to React Native!
</Text>
<Text style={styles.instructions}>
To get started, edit index.ios.js
</Text>
<Text style={styles.instructions}>
Press Cmd+R to reload,{'\n'}
Cmd+D or shake for dev menu
</Text>
</View>
);
}
});
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});
I've been able to use Babel to transpile the JSX syntax as well as use Mockery to mock the React library methods createClass and StyleSheet.create, but at the end of the day, I can't seem to create any meaningful tests.
You should mock up React Native package as well as set babel transformer and some other settings. Maybe you could check unit tests for my component, React Native Router Flux:
https://github.com/aksonov/react-native-router-flux/tree/master/tests
To run tests with Jest you should replace ReactNative with React using __mocks__ folder, use TestUtils with shallow renderer and maybe react-shallow-renderer-helpers to lookup virtual tree.
I've made sample repository with unit tests here and article about my way through it here
In the end I setup a repo with TravisCI using Mocha for BDD style unit tests. You can see the repo at: https://github.com/sghiassy/react-native-sglistview
Take a look at ReactNative's UIExplorer example project, which is set up with several hybrid XCTest & require('NativeModules').TestModule test suites.
https://github.com/facebook/react-native/tree/master/Examples/UIExplorer/UIExplorerIntegrationTests/js
Related
This has been addressed twice here, but more of a question of how to get around it. I know how... you can just delete App.js. But my question is whether App.js will be needed down the road once it has been packaged for distribution, or at any other time. If so, I'd rather find another solution other than just deleting the file.
I'll provide the code in App.js. This is the basic file that is created from either vue-native init or expo init.
Looked at previous posts:
Vue native is always executing App.js instead of .vue
App.vue is not working in Vue-Native application
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
export default function App() {
return (
<View style={styles.container}>
<Text>Open up App.js to start working on your app!</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
If you're using webpack you can get around this by setting the entry point:
module.exports = {
...
entry: 'YourNewEntryPoint'
...
}
Without Webpack I'm not sure if there's a way to get around App.js being the entry point.
Im trying to setup PushNotiifactions on react-native IOS using AWS Amplify and PinPoint. I followed the instructions on AWS-Amplify to setup push notifications on React Native IOS but I noticed that I'm not getting a token back after some debugging noticed that Notification import is doesn't have configure, onRegeister or onNotification methods
My dependencies:
"dependencies": {
"#aws-amplify/analytics": "^1.2.10",
"#aws-amplify/pushnotification": "^1.0.22",
"aws-amplify-react-native": "^2.1.7",
"react": "16.6.3",
"react-native": "0.58.3"
},
My App.js
import React, { Component } from "react";
import {
StyleSheet,
Text,
View,
PushNotificationIOS,
} from "react-native";
import aws_exports from "./aws-exports";
import Analytics from "#aws-amplify/analytics";
import PushNotification from "#aws-amplify/pushnotification";
// PushNotification need to work with Analytics
Analytics.configure(aws_exports);
Analytics.enable();
PushNotification.configure(aws_exports);
type Props = {};
export default class App extends Component {
componentDidMount(){
console.log('PN',PushNotification);
// get the notification data when notification is received
PushNotification.onNotification(notification => {
// Note that the notification object structure is different from Android and IOS
console.log("in app notification", notification);
// required on iOS only (see fetchCompletionHandler docs: https://facebook.github.io/react-native/docs/pushnotificationios.html)
notification.finish(PushNotificationIOS.FetchResult.NoData);
});
// get the registration token
PushNotification.onRegister(token => {
console.log("in app registration", token);
});
// get the notification data when notification is opened
PushNotification.onNotificationOpened(notification => {
console.log("the notification is opened", notification);
});
}
render() {
return (
Welcome to React Native!
To get started, edit App.js
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#F5FCFF"
},
welcome: {
fontSize: 20,
textAlign: "center",
margin: 10
},
instructions: {
textAlign: "center",
color: "#333333",
marginBottom: 5
}
});
Those PushNotification methods are part of its prototype, you should use something like this:
console.log('PN', Object.getOwnPropertyNames(Object.getPrototypeOf(PushNotification)))
Regarding not getting a token at onRegister, are you testing it on a real device instead of an emulator?
I am beginner in react native.I want to upload files to aws s3 once after taking the photo in using react native camera. I am able to take picture using react native camera. Now, I need to upload to s3 bucket. When I search for this, I get many documents and I get confused how to use this.
I have done file uploading to amazon s3 and downloading form s3 using php. But in react native I am not getting how to do this as I am a beginner . I searched in aws s3 file upload documents there I got using php, java and .Net etc..But I did not get for react native.
Can anyone help me to do this.
My code to take image in react native is,
import React, {Component} from 'react';
import {Platform, StyleSheet, Text,TouchableOpacity, View} from 'react-native';
import ImagePicker from 'react-native-image-picker';
import RNS3 from 'react-native-aws3';
export default class App extends Component<Props> {
takePic(){
ImagePicker.showImagePicker({},(responce)=>{
console.log(responce);
const file ={
uri : responce.path,
name : responce.fileName,
type : responce.type,
}
console.log(file);
const config ={
keyPrefix :'uploads/',
bucket : '**',
region :'***',
accessKey:'***',
secretKey :'***',
successActionStatus :201
}
RNS3.put(file ,config)
.then((responce) => {
console.log(responce);
})
})
}
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>Welcome v</Text>
<TouchableOpacity onPress={this.takePic.bind(this)}>
<Text>Take Picture</Text>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});
When I select the picture from galary / cliked new photo it gives me below error,
02-05 09:10:52.738 12357 12389 I ReactNativeJS: { uri: '/storage/emulated/0/Pictures/image-cb48f179-5b00-4e0a-93ef-74206f76c4e4.jpg',
02-05 09:10:52.738 12357 12389 I ReactNativeJS: name: 'image-cb48f179-5b00-4e0a-93ef-74206f76c4e4.jpg',
02-05 09:10:52.738 12357 12389 I ReactNativeJS: type: 'image/jpeg' }
02-05 09:10:52.738 12357 12389 E ReactNativeJS: undefined is not an object (evaluating '_reactNativeAws.default.put')
How to resolve this ReactNativeJS: undefined is not an object (evaluating '_reactNativeAws.default.put').
Can you please help me out to resolve this.
I have resolve my error :):).Finally, It got worked after 4 days. So happy.
I have installed react-native-file-upload. Now it works Perfectly.
npm install react-native-file-upload --save
I'm new to Mocha and I am trying to use it to test a simple React component. The test would pass if the react component doesn't have any CSS styling but throws a syntax error if the tag within the React component contains any className:
Testing.react.js
import React from 'react';
export default class Testing extends React.Component {
render() {
return (
<section>
<form>
<input type="text" />
</form>
</section>
);
}
}
testing.jsx
import {
React,
sinon,
assert,
expect,
TestUtils
} from '../../test_helper';
import TestingSample from '../../../app/components/Testing.react.js';
describe('TestingSample component', function(){
before('render and locate element', function(){
var renderedComponent = TestUtils.renderIntoDocument(
<TestingSample />
);
var inputComponent = TestUtils.findRenderedDOMComponentWithTag(
renderedComponent, 'input'
);
this.inputElement = inputComponent.getDOMNode();
});
it('<input> should be of type "text"', function () {
assert(this.inputElement.getAttribute('type') === 'text');
});
})
The test would pass:
> mocha --opts ./test/javascripts/mocha.opts --compilers js:babel/register --recursive test/javascripts/**/*.jsx
TestSample component
✓ <input> should be of type "text"
1 passing (44ms)
after I added the className inside of the input tag an error shows up:
import React from 'react';
import testingStyle from '../../scss/components/landing/testing.scss';
export default class Testing extends React.Component {
render() {
return (
<section>
<form>
<input type="text" className="testingStyle.color" placeholder="Where would you like to dine" />
</form>
</section>
);
}
}
Test result:
SyntaxError: /Users/../../../Documents/project/app/scss/components/landing/testing.scss: Unexpected token (1:0)
> 1 | .color {
| ^
2 | color: red;
3 | }
I've searched online but no luck so far. Am I missing something? Please help me out or point me to the right direction would be greatly appreciated.
I'm currently using:
Node Express Server
React
React-router
Webpack
Babel
Mocha
Chai
Sinon
Sinon-Chai
There is a babel/register style hook to ignore style imports:
https://www.npmjs.com/package/ignore-styles
Install it:
npm install --save-dev ignore-styles
Run tests without styles:
mocha --require ignore-styles
you can use a css compilers run mocha, the compiler js as follow:
css-dnt-compiler.js
function donothing() {
return null;
}
require.extensions['.css'] = donothing;
require.extensions['.less'] = donothing;
require.extensions['.scss'] = donothing;
// ..etc
and run the mocha command like this:
mocha --compilers js:babel-core/register,css:css-dnt-compiler.js --recursive
My same answer as here, this is what I used to get working on Babel 6
package.json
"scripts": {
"test": "mocha --compilers js:babel-core/register
--require ./tools/testHelper.js 'src/**/*-spec.#(js|jsx)'",
tools/testHelper.js
// Prevent mocha from interpreting CSS #import files
function noop() {
return null;
}
require.extensions['.css'] = noop;
This enables you to have your tests inside your src folder alongside your components. You can add as many extensions as you would like with require.extensions.
Since you're using webpack, use null-loader to load null when webpack encounters a required CSS/LESS/SASS/etc file in your components. Install via npm and then update your webpack config to include the loader:
{
test: /(\.css|\.less|.\scss)$/,
loader: 'null-loader'
}
Obviously this will prevent you from loading CSS in your actual application, so you'll want to have a separate webpack config for your test bundle that uses this loader.
For those looking how to handle this in jest - you just add a handler for style files:
// package.json
{
"jest": {
"moduleNameMapper": {
"\\.(css|less|scss|sass)$": "<rootDir>/__mocks__/styleMock.js"
}
}
}
// __mocks__/styleMock.js
module.exports = {};
More here.
None of these solutions worked for me, as I'm using mocha-webpack, and it doesn't accept the "--compilers" switch. I implemented the ignore-styles package, as described in the most popular answer, but it seemed inert, with no difference in my Istanbul coverage report (.less files still being tested).
The problem is the .less loader that I was using in my webpack.config.test.js file. Simply swapping less-loader for null-loader fixed my problem.
module: {
rules: [
{
test: /\.less$/,
use: ['null-loader']
}
]
}
For me, this is by far the simplest solution, and targets my testing configuration directly, rather than having to alter/add to the package.json scripts, or worse, add new .js files.
One simple way is to import 'ignore-styles'; in your test classes..
The code below works without any dependencies. Just add it to the top of the tests.
var Module = require('module');
var originalRequire = Module.prototype.require;
Module.prototype.require = function () {
if (arguments[0] && arguments[0].endsWith(".css"))
return;
return originalRequire.apply(this, arguments);
};
Although very old, this question is still relevant, so let me throw in another solution.
Use pirates, a package to add hooks to require() - if you use Babel, you already have it.
Example code:
// .test-init.js
const { addHook } = require('pirates');
const IGNORE_EXTENSIONS = ['.scss', '.svg', '.css'];
addHook((code, filename) => '', { exts: IGNORE_EXTENSIONS });
This way you can call mocha like so: mocha --require .test-init.js [whatever other parameters you use]
This is straightforward, elegant and unlike ignore-styles it doesn't imply you are ignoring styles only. Also, this is easily extendable if you need to apply some more trickery to your tests like mocking entire modules.
I'm writing integrations tests for an Ember app using QUnit. Is there anyway to test if an element is visible?
My experience with integration testing comes from Capybara which detects only visible elements by default.
If you have HTML fixture as described in the guide you should be able to check the elements using jQuery:
test( "search, close", function() {
//SNIP
// Note the use of a real element here:
element = $( "#autocomplete" ).autocomplete({
source: data,
minLength: 0
}),
menu = element.autocomplete( "widget" );
//SNIP
ok( menu.is( ":visible" ), "menu is visible after search" );
//SNIP
});
Code source:
Test for visible in QUnit test of JQueryUI widget