I would like to check the number of MenuItems in the popover of the IconMenu when it gets clicked but I'm not sure how to access the 'PopoverDefaultAnimation' or am not sure about the best way to do this. Any help would be appreciated. When I try to console.log the menuitems, the result is []
My JSX file,
import React, {PropTypes} from 'react'
/** material-ui **/
import IconMenu from 'material-ui/IconMenu'
import IconButton from 'material-ui/IconButton'
import MenuItem from 'material-ui/MenuItem'
import Divider from 'material-ui/Divider'
import Help from 'material-ui/svg-icons/action/help-outline'
import getMuiTheme from 'material-ui/styles/getMuiTheme'
export default class MndyHelp extends React.Component{
constructor(props) {
//console.log('Main: constructor()');
super(props);
}
static childContextTypes = {
muiTheme: React.PropTypes.object
}
getChildContext() {
return {
muiTheme: getMuiTheme()
}
}
render(){
var urlLink = "https://www.google.com";
return(
<IconMenu
iconButtonElement={
<IconButton style={ {padding: 0, width: "auto", height: "auto", right: 44, top: 4 } } iconStyle={{ height: 30, width: 30, fill: "#304954"}}><Help/></IconButton>}>
<MenuItem onTouchTap={() => {window.open(urlLink, '_blank');}} primaryText='Item1'/>
<MenuItem onTouchTap={() => {window.open(urlLink, '_blank');}} primaryText='Item2'/>
</IconMenu>
);
}
}
My unit test
import React from 'react'
import {renderIntoDocument,
scryRenderedDOMComponentsWithTag,
scryRenderedComponentsWithType,
Simulate
} from 'react-addons-test-utils'
import chai from 'chai'
import ReactDOM from 'react-dom'
import IconButton from 'material-ui/IconButton'
import IconMenu from 'material-ui/IconMenu'
import MenuItem from 'material-ui/MenuItem'
import Popover from 'material-ui/Popover';
import Help from 'material-ui/svg-icons/action/help-outline'
import injectTapEventPlugin from 'react-tap-event-plugin';
var should = chai.should(),
expect = chai.expect;
import MndyHelp from './MndyHelp.jsx';
describe('<MndyHelp/>', () => {
injectTapEventPlugin();
it('should have 2 menuItems', () => {
var domElement = renderIntoDocument(<MndyHelp/>),
buttons = scryRenderedComponentsWithType(domElement,IconButton),
firstButton = ReactDOM.findDOMNode(buttons[0]);
Simulate.touchTap(firstButton);
var popOver = scryRenderedComponentsWithType(domElement,Popover);
var menuItem = scryRenderedComponentsWithType(domElement,MenuItem);
//make sure popover is open i.e. true
expect(popOver[0].props.open).to.equal(true);
//Make sure menu items exist
console.log(menuItem); //----> this prints [] instead of the menuitems
expect(menuItem.length).to.not.equal(0);
expect(menuItem.length).to.equal(2);
});
});
Related
im trying to to convert below code snippet to JEST unit testing but its throwing error please help me out in resolving it
import React from 'react'
import { BrowserRouter as Router, Switch, Route} from 'react-router-dom';
import IdleTimer from 'react-idle-timer';
import { ApolloProvider } from '#apollo/react-hooks';
import Dashboard from '../pages/Dashboard';
import Loader from '../components/Loader';
import Alert from '../components/Alert';
import NoAccess from '../pages/NoAccess';
import { GQL } from '../services/GQL';
import { IdleTimeOutModal } from './IdleTimeoutModal';
import PropTypes from 'prop-types';
import 'bootstrap/dist/css/bootstrap.min.css';
import '../App.scss';
import '../assets/css/loader.scss';
import AuthenticatedRoute from '../guards/AuthenticatedRoute';
import auth from '../services/Auth';
import { connect } from 'react-redux';
class Layout extends React.Component {
constructor(props){
super(props);
this.state = {
timeout:1000 * 900 * 1,
showModal: false,
userLoggedIn: window.localStorage.getItem('loginUser'),
isTimedOut: false,
}
this.idleTimer = null
this.onAction = this._onAction.bind(this)
this.onActive = this._onActive.bind(this)
this.onIdle = this._onIdle.bind(this)
this.handleClose = this.handleClose.bind(this)
this.handleLogout = this.handleLogout.bind(this)
}
_onAction(e) {
// console.log('user did something', e)
this.setState({isTimedOut: false})
}
_onActive(e) {
// console.log('user is active', e)
this.setState({isTimedOut: false})
}
_onIdle(e) {
// console.log('user is idle', e)
const isTimedOut = this.state.isTimedOut
if (isTimedOut) {
this.setState({showModal: false})
window.localStorage.setItem('loginUser', 'false');
} else {
this.setState({showModal: true})
this.idleTimer.reset();
this.setState({isTimedOut: true})
}
}
handleClose() {
this.setState({showModal: false})
}
handleLogout() {
this.setState({showModal: false})
auth.signout();
}
render(){
// console.log(window.location)
const {match} = window.location.href;
// const { match } = this.location
return(
<>
<IdleTimer
ref={ref => { this.idleTimer = ref }}
element={document}
onActive={this.onActive}
onIdle={this.onIdle}
onAction={this.onAction}
debounce={250}
timeout={this.state.timeout} />
<div className="">
<ApolloProvider client={GQL}>
<Router>
<Switch>
{/* <Route component={NoAccess} path="/no-access" exact={true} /> */}
<AuthenticatedRoute path={`${window.location.pathname}`} component={Dashboard} />
</Switch>
</Router>
{/* <Loader isOpen={loader.isLoading} /> */}
{/* <Alert /> */}
</ApolloProvider>
<IdleTimeOutModal
showModal={this.state.showModal}
handleClose={this.handleClose}
handleLogout={this.handleLogout}
/>
</div>
</>
)
}
}
***JEST throwing error while converting to JEST - ShallowWrapper::state() can only be called on class components
jest help***
export default connect((props) =>({
match: props.uiel.isRequired,
history: props.uiel.isRequired
}))(Layout);
import React from 'react';
import { BrowserRouter as Router, Switch, Route} from 'react-router-dom';
import { render, cleanup, fireEvent } from '#testing-library/react';
import '#testing-library/jest-dom/extend-expect';
import Enzyme, { shallow, mount } from 'enzyme';
import Layout from './Layout';
import Adapter from 'enzyme-adapter-react-16';
import { Provider } from "react-redux";
import configureMockStore from "redux-mock-store";
import { IdleTimeOutModal } from './IdleTimeoutModal';
import { wrap } from 'module';
Enzyme.configure({ adapter: new Adapter() })
const mockStore = configureMockStore();
let handleLogout:any;
let showModal: any;
let handleClose:any;
let remainingTime:any;
let _onAction:any;
let _onIdle:any;
let _onActive:any;
let idleTimer:any;
describe("Render Layout Component", ()=>{
let store;
let wrapperlayout:any;
beforeEach(()=>{
store = mockStore({
loader: false
});
wrapperlayout = shallow(
<Provider store={store}>
<Layout />
</Provider>
);
});
it('should render the value of color', () => {
wrapperlayout.setProps({ timeout:1000 * 900 * 1 });
wrapperlayout.setProps({ showModal: false });
wrapperlayout.setProps({ userLoggedIn: window.localStorage.getItem('loginUser') });
wrapperlayout.setProps({ isTimedOut: false });
//expect(wrapper.state('color')).toEqual('transparent');
});
it("should increment index - function test", () => {
//const app = shallow(<Normal />);
expect(wrapperlayout.state("isTimedOut")).toEqual('false');
wrapperlayout.instance()._onAction();
expect(wrapperlayout.state("isTimedOut")).toEqual('false');
});
test("Render Modal Layout", ()=>{
expect(wrapperlayout.exists()).toBe(true);
});
});
So i set up mobx and the files show no error in visual studio code and the react client app compile just fine and it shows the list of Departments but there is also a button thats not working its set up all fine and the onClick event is all fine but it doesnt work I had problems with mobx because its greater than version 6 or idk its version so i had to add the construvtor to display the list
Department store
import {observable, action, makeObservable} from 'mobx';
import { createContext } from 'react';
import agent from '../api/agent';
import { IDepartment } from '../models/department';
class DepartmentStore {
#observable departments: IDepartment[] = [];
#observable selectedDepartment: IDepartment | undefined;
#observable loadingInitial = false;
#observable editMode =false;
constructor() {
// Just call it here
makeObservable(this);
}
#action loadDepartments= () => {
this.loadingInitial = true;
agent.Departments.list()
.then(departments => {
departments.forEach((department) => {
this.departments.push(department);
})
}).finally(() => this.loadingInitial = false);
};
#action selectDepartment = (id: string) => {
this.selectedDepartment = this.departments.find(d => d.id === id);
this.editMode = false;
}
}
export default createContext(new DepartmentStore());
so everything here shows no error below ill display the DepartmentList code where it contains the button thats now functioning
import { observer } from "mobx-react-lite";
import React, { SyntheticEvent, useContext } from "react";
import { Item, Button, Segment } from "semantic-ui-react";
import { IDepartment } from "../../../app/models/department";
import DepartmentStore from "../../../app/stores/departmentStore";
interface IProps {
deleteDepartment: (event: SyntheticEvent<HTMLButtonElement>,id: string) => void;
submitting: boolean;
target: string;
}
export const DepartmentList: React.FC<IProps> = ({
deleteDepartment,
submitting,
target
}) => {
const departmentStore = useContext(DepartmentStore);
const {departments, selectDepartment} = departmentStore;
return (
<Segment clearing>
<Item.Group divided>
{departments.map((department) => (
<Item key={department.id}>
<Item.Content style={{ display: "flex" }}>
<Item.Header style={{ width: "100%", marginTop: "1em" }}>
{department.name}
</Item.Header>
<Item.Extra>
<Button
name={department.id}
loading={target === department.id && submitting}
onClick={(e) => deleteDepartment(e, department.id)}
content="Delete"
color="red"
floated="right"
/>
<Button
onClick={() => selectDepartment(department.id)}
content="View"
color="blue"
floated="right"
/>
</Item.Extra>
</Item.Content>
</Item>
))}
</Item.Group>
</Segment>
);
};
export default observer(DepartmentList)
;
I try to run unit tests on vue components, the compnents are written with #vue/composition-api package and they also use vuetify.
The Application runs like expected, but when I run the tests I don't have access to the breakpoint property under context.root.$vuetify. When I print the context.root.$vuetify a see the vue component instance.
The error is "Cannot read property 'mdAndDown' of undefined" when i try to access it like that:
context.root.$vuetify.breakpoint.mdAndDown
This is is my jest config file:
module.exports = {
preset: '#vue/cli-plugin-unit-jest/presets/typescript-and-babel',
transform: { '^.*\\.js$': 'babel-jest' },
transformIgnorePatterns: ['node_modules/(?!vue-router|#babel|vuetify)'],
setupFiles: [
"<rootDir>/tests/unit/setup-env.ts",
],
};
This is the Component file:
<template>
<v-app
class="sst-app-container"
>
<cmp-loading
v-show="!loadedBasic"
/>
<div
id="app-wrp"
v-show="loadedBasic"
>
<cmp-side-bar />
<v-content
class="fill-height"
>
<router-view></router-view>
</v-content>
</div>
</v-app>
</template>
<script lang="ts">
import {
computed, createComponent, onMounted, reactive, toRefs, watch,
} from '#vue/composition-api';
import basicSetup from '#/modules/core/composables/basic-setup';
import initMd from '#/modules/core/devices/mouse/composables/init-md';
import store from '#/stores';
import cmpSideBar from '../components/sidebar/CoreSideBar.mouse.vue';
import cmpLoading from '../components/loading/CoreLoading.vue';
export default createComponent({
components: {
cmpLoading,
cmpSideBar,
},
setup(props, context) {
console.log(context.root.$vuetify)
const basics = basicSetup();
return {
...basics,
};
},
});
</script>
This is my test:
import Vue from 'vue';
import Vuetify from 'vuetify';
import BtnCmp from '../../../../../components/vc-btn.vue';
import CmApi from '#vue/composition-api';
import { library } from '#fortawesome/fontawesome-svg-core';
import { FontAwesomeIcon } from '#fortawesome/vue-fontawesome';
import {
faPlug,
faSignOut,
faCog,
faUser,
faTachometer,
faArrowLeft,
faArrowRight,
} from '#fortawesome/pro-duotone-svg-icons';
library.add(
faPlug,
faSignOut,
faCog,
faUser,
faTachometer,
faArrowLeft,
faArrowRight,
);
import { Breakpoint, Theme, Application, Goto, Icons, Lang, Presets } from 'vuetify/lib/services';
import {
mount,
createLocalVue,
} from '#vue/test-utils';
import Core from '../views/Core.mouse.vue';
const vue = createLocalVue();
vue.component('font-awesome-icon', FontAwesomeIcon);
vue.component('vc-btn', BtnCmp);
vue.use(Vuetify);
vue.use(CmApi);
describe('Core', () => {
let vuetify;
beforeEach(() => {
vuetify = new Vuetify({
mocks: {
breakpoint: new Breakpoint({
breakpoint: {
scrollBarWidth: 0,
thresholds: {
xs: 0,
sm: 0,
md: 0,
lg: 0,
},
},
},
});
});
it('renders the correct markup', async () => {
// Now mount the component and you have the wrapper
const wrapper = mount(Core, {
localVue: vue,
vuetify,
stubs: ['router-link', 'router-view'],
mocks: {
$t: () => 'some specific text'
},
});
expect(wrapper.html()).toContain('....');
});
});
This can be solved by adding a new instance of vuetify to the wrapper vuetify: new Vuetify()
I'm trying to to do integration tests, by mounting a smart connected component.
The fetch action that is within componentDidMount of my smart components dispatches just fine, and it's taken by my Saga. Although it is supposed to put a success action, it doesn't .
Here is my testing code :
import React from 'react'
import { Provider } from 'react-redux'
import configureMockStore from 'redux-mock-store'
import MockAdapter from 'axios-mock-adapter'
import Enzyme,{ mount,render } from 'enzyme'
import Tasks from '../containers/tasks.jsx'
import createSagaMiddleware from 'redux-saga'
import axios from "axios";
import Adapter from 'enzyme-adapter-react-16';
import mySaga from '../actions/tasksSaga'
import { createStore, combineReducers, applyMiddleware } from 'redux'
import reducer from '../reducers'
Enzyme.configure({ adapter: new Adapter() });
describe('App', () => {
// create the saga middleware
const sagaMiddleware = createSagaMiddleware()
const mock = new MockAdapter(axios)
const state = {
tasksReducer:{
tasks:[]
},
uiReducer :{
}
};
const todos = [
{
id: 1,
title: 'todo1',
description: 'nice'
},
{
id: 2,
title: 'todo2',
description: 'nice'
}
]
beforeAll(() => {
mock.onGet('http://localhost:9001/tasks').reply(200, {tasks:todos})
})
it('renders an App container', () => {
const store = createStore(
reducer,
applyMiddleware(sagaMiddleware),
)
sagaMiddleware.run(mySaga)
const wrapper = mount(
<Provider store={store}>
<Tasks />
</Provider>
)
wrapper.instance().forceUpdate()
expect(wrapper.find('Task')).toHaveLength(3)
})
})
My success action is never called although data is good.
I am trying to unit test my reactjs component:
import React from 'react';
import Modal from 'react-modal';
import store from '../../../store'
import lodash from 'lodash'
export class AddToOrder extends React.Component {
constructor(props) {
super(props);
this.state = {checked: false}
//debugger
}
checkBoxChecked() {
return true
}
render() {
console.log('testing=this.props.id',this.props.id )
return (
<div className="order">
<label>
<input
id={this.props.parent}
checked={this.checkBoxChecked()}
onChange={this.addToOrder.bind(this, this.props)}
type="checkbox"/>
Add to order
</label>
</div>
)
}
}
export default AddToOrder;
Just to get started I am already struggling to assert the checkBoxChecked method:
import React from 'react-native';
import {shallow} from 'enzyme';
import {AddToOrder} from '../app/components/buttons/addtoorder/addtoorder';
import {expect} from 'chai';
import {mount} from 'enzyme';
import jsdom from 'jsdom';
const doc = jsdom.jsdom('<!doctype html><html><body></body></html>')
global.document = doc
global.window = doc.defaultView
let props;
beforeEach(() => {
props = {
cart: {
items: [{
id: 100,
price: 2000,
name:'Docs'
}]
}
};
});
describe('AddToOrder component', () => {
it('should be handling checkboxChecked', () => {
const wrapper = shallow(<AddToOrder {...props.cart} />);
expect(wrapper.checkBoxChecked()).equals(true); //error appears here
});
});
```
How can I unit test a method on the component? This is the error I am getting:
TypeError: Cannot read property 'checked' of undefined
You are almost there. Just change your expect to this:
expect(wrapper.instance().checkBoxChecked()).equals(true);
You can go through this link to know more about testing component methods using enzyme
For those who find the accepted answer as not working, try using .dive() on your shallow wrapper before using .instance():
expect(wrapper.dive().instance().somePrivateMethod()).toEqual(true);
Reference: Testing component methods with enzyme
Extend of previous answer.
If you have connected component (Redux) , try next code :
const store=configureStore();
const context = { store };
const wrapper = shallow(
<MyComponent,
{ context },
);
const inst = wrapper.dive().instance();
inst.myCustomMethod('hello');