admin管理员组文章数量:1391836
I was trying to test my ponents and everytime my tests fail, and i'm not able to figure out where the problem is located.
Login.test.js :
import { Meteor } from 'meteor/meteor';
import React from 'react';
import expect from 'expect';
import { mount } from 'enzyme';
import { Login } from './Login';
if (Meteor.isClient) {
describe("Login", function() {
it("should show error messages", function() {
const error = "This is not working";
const wrapper = mount(<Login loginWithPassword={() => {}}/>);
wrapper.setState({ error: error });
expect(wrapper.find("p").text()).toBe(error);
wrapper.setState({ error: "" });
expect(wrapper.find("p").length).toBe(0);
});
it("should called loginWithPassword with the form data", function() {
const email = "[email protected]";
const password = "password1234";
const spy = expect.createSpy();
const wrapper = mount(<Login loginWithPassword={spy}/>);
wrapper.ref("email").node.value = email;
wrapper.ref("password").node.value = password;
wrapper.find("form").simulate("submit");
expect(spy.calls[0].arguments[0]).toEqual({email: email});
expect(spy.calls[0].arguments[1]).toEqual(password);
});
it("should set loginWithPassword callback errors", function() {
});
})
}
Login.js :
import React from "react";
import { Link, Redirect } from "react-router-dom";
import { Meteor } from "meteor/meteor";
import { createContainer } from 'meteor/react-meteor-data';
export class Login extends React.Component {
constructor(props) {
super(props);
this.onSubmit = this.onSubmit.bind(this);
this.state = {
error: ""
};
}
onSubmit(e) {
e.preventDefault();
let email = this.refs.email.value.trim();
let password = this.refs.password.value.trim();
this.props.loginWithPassword({ email }, password, err => {
if (err) {
this.setState({ error: "Unable to login. Check your credentials." });
} else {
this.setState({ error: "" });
}
});
}
render() {
return (
<div className="boxed-view">
<div className="boxed-view__box">
<h1>Login</h1>
{this.state.error
? <p className="boxed-view__box__error">{this.state.error}</p>
: undefined}
<form
onSubmit={this.onSubmit}
noValidate
className="boxed-view__form"
>
<input type="email" ref="email" name="email" placeholder="Email" />
<input
type="password"
ref="password"
name="password"
placeholder="Password"
/>
<button className="button">Login</button>
</form>
<Link to="/signup">Not registered yet?</Link>
</div>
</div>
);
}
}
Login.PropTypes = {
loginWithPassword: React.PropTypes.func.isRequired
};
export default createContainer(() => {
return {
loginWithPassword: Meteor.loginWithPassword
}
}, Login);
Mocha client and server test :
Screenshot Chrome Mocha tests
Thank you for helping me out!
I was trying to test my ponents and everytime my tests fail, and i'm not able to figure out where the problem is located.
Login.test.js :
import { Meteor } from 'meteor/meteor';
import React from 'react';
import expect from 'expect';
import { mount } from 'enzyme';
import { Login } from './Login';
if (Meteor.isClient) {
describe("Login", function() {
it("should show error messages", function() {
const error = "This is not working";
const wrapper = mount(<Login loginWithPassword={() => {}}/>);
wrapper.setState({ error: error });
expect(wrapper.find("p").text()).toBe(error);
wrapper.setState({ error: "" });
expect(wrapper.find("p").length).toBe(0);
});
it("should called loginWithPassword with the form data", function() {
const email = "[email protected]";
const password = "password1234";
const spy = expect.createSpy();
const wrapper = mount(<Login loginWithPassword={spy}/>);
wrapper.ref("email").node.value = email;
wrapper.ref("password").node.value = password;
wrapper.find("form").simulate("submit");
expect(spy.calls[0].arguments[0]).toEqual({email: email});
expect(spy.calls[0].arguments[1]).toEqual(password);
});
it("should set loginWithPassword callback errors", function() {
});
})
}
Login.js :
import React from "react";
import { Link, Redirect } from "react-router-dom";
import { Meteor } from "meteor/meteor";
import { createContainer } from 'meteor/react-meteor-data';
export class Login extends React.Component {
constructor(props) {
super(props);
this.onSubmit = this.onSubmit.bind(this);
this.state = {
error: ""
};
}
onSubmit(e) {
e.preventDefault();
let email = this.refs.email.value.trim();
let password = this.refs.password.value.trim();
this.props.loginWithPassword({ email }, password, err => {
if (err) {
this.setState({ error: "Unable to login. Check your credentials." });
} else {
this.setState({ error: "" });
}
});
}
render() {
return (
<div className="boxed-view">
<div className="boxed-view__box">
<h1>Login</h1>
{this.state.error
? <p className="boxed-view__box__error">{this.state.error}</p>
: undefined}
<form
onSubmit={this.onSubmit}
noValidate
className="boxed-view__form"
>
<input type="email" ref="email" name="email" placeholder="Email" />
<input
type="password"
ref="password"
name="password"
placeholder="Password"
/>
<button className="button">Login</button>
</form>
<Link to="/signup">Not registered yet?</Link>
</div>
</div>
);
}
}
Login.PropTypes = {
loginWithPassword: React.PropTypes.func.isRequired
};
export default createContainer(() => {
return {
loginWithPassword: Meteor.loginWithPassword
}
}, Login);
Mocha client and server test :
Screenshot Chrome Mocha tests
Thank you for helping me out!
Share Improve this question asked Apr 27, 2017 at 7:58 KaldroghKaldrogh 731 gold badge2 silver badges4 bronze badges2 Answers
Reset to default 5it's a shame that nobody answered this yet.
Hopefully you've eventually realized that the issue is the result of React Router's ponent rendering outside of the context of a Router ponent.
You need to wrap your ponent in a ponent to resolve this and then make the appropriate changes as your wrapper variable will change and your ponent will no longer be the root ponent, which will change how you operate on the wrapper variable.
You have a couple of issues with your code, Please use the following & let me know if you still have any problems
import { Meteor } from 'meteor/meteor';
import React from 'react';
import expect from 'expect';
import { configure } from 'enzyme';
import { mount } from 'enzyme';
import Adapter from 'enzyme-adapter-react-15';
configure({ adapter: new Adapter() });
import { Login } from './Login';
//notice we are importing the "raw" named-export Login not the containerized default one.
if (Meteor.isClient) {
describe('Login', () => {
it('Should show error messages', () => {
const error = 'This is not working';
const wrapper = mount(<Login loginWithPassword={() => { }} />);
wrapper.setState({ error: error });
expect(wrapper.find('p').text()).toBe(error);
wrapper.setState({error: ''});
expect(wrapper.find('p').length).toBe(0);
});
it('should call loginWithPassword with the form data', () => {
const email = '[email protected]';
const password = 'password123';
const spy = expect.createSpy();
const wrapper = mount (<Login loginWithPassword={spy}/>);
//notice the change, node ==> instance() due to deprecation of use of private properties by enzyme.
wrapper.find('input[name="email"]').instance().value = email;
wrapper.find('input[name="password"]').instance().value = password;
wrapper.find('form').simulate('submit');
expect(spy.calls[0].arguments[0]).toEqual({email:email});
expect(spy.calls[0].arguments[1]).toBe(password);
//above we used toBe (instead of toEqual) because second argument is a variable not object
});
});
}
Summary of issues in the original code
[1] Use of node
in referencing DOM objects as in the below snippet is deprecated by enzyme
wrapper.ref("email").node.value = email;
Furthermore, React has deprecated the use of string refs. You should use callbacks to avoid console warnings.
Hence, The right way is to use instance()
and find()
as per the below snippet
wrapper.find('input[name="email"]').instance().value = email;
[2] declaration in the original code defined email as object and password as variable (snippet below)
this.props.loginWithPassword({ email }, password, err => {
Hence, we should pick the right assertion method from expect
to handle each case as per the below snippet
expect(spy.calls[0].arguments[0]).toEqual({email:email});
expect(spy.calls[0].arguments[1]).toBe(password);
本文标签: javascriptReactEnzymeCannot read property 39history39 of undefinedStack Overflow
版权声明:本文标题:javascript - React, Enzyme : Cannot read property 'history' of undefined - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744770410a2624303.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论