我配置了一个容器以使用redux-mock-store测试到最新版本,但出现了一些问题。 find()函数不起作用。我曾经收到零节点和零长度。当我使用mount代替浅函数时,此方法可行,但出现无法识别redux mapDispatchToProps的问题。我如何保证将采取行动?我不想测试商店,但不想测试动作功能,因为我使用thunk。我的推理对吗?
我的容器:
import React, { useState } from 'react'
import { connect } from 'react-redux'
import { Redirect } from 'react-router-dom'
import styles from './Auth.module.css'
import Input from '../../components/UI/Input/Input'
import Button from '../../components/UI/Button/Button'
import Logo from '../../components/UI/Logo/Logo'
import Spinner from '../../components/UI/Spinner/Spinner'
import { auth as authAction } from '../../store/actions/index'
import { checkValidity } from '../../shared/utility'
export const Auth = (props) => {
const [formIsValid, setFormIsValid] = useState(false)
const [authForm, setAuthForm] = useState({
email: {
elementType: 'input',
elementConfig: {
type: 'email',
placeholder: 'Enter your email'
},
value: '',
validation: {
required: true,
isEmail: true
},
valid: false,
touched: false
},
password: {
elementType: 'input',
elementConfig: {
type: 'password',
placeholder: 'Enter your password'
},
value: '',
validation: {
required: true,
minLength: 6
},
valid: false,
touched: false
},
})
const inputChangeHandler = (event, controlName) => {
const updatedControls = {
...authForm,
[controlName]: {
...authForm[controlName],
value: event.target.value,
valid: checkValidity(event.target.value, authForm[controlName].validation),
touched: true
}
}
let formIsValid = true;
for (let inputIdentifier in updatedControls) {
formIsValid = updatedControls[inputIdentifier].valid && formIsValid
}
setAuthForm(updatedControls)
setFormIsValid(formIsValid)
}
const submitHandler = (event, signup) => {
event.preventDefault()
props.onAuth(
authForm.email.value,
authForm.password.value,
signup
)
}
const formElementsArray = []
for (let key in authForm) {
formElementsArray.push({
id: key,
config: authForm[key]
})
}
let formFields = formElementsArray.map(formElement => (
<Input
key={formElement.id}
elementType={formElement.config.elementType}
elementConfig={formElement.config.elementConfig}
value={formElement.config.value}
invalid={!formElement.config.valid}
shouldValidate={formElement.config.validation}
touched={formElement.config.touched}
changed={(event) => inputChangeHandler(event, formElement.id)} />
))
let form = (
<>
<form onSubmit={(event) => submitHandler(event, false)}>
{formFields}
<Button
disabled={!formIsValid}
btnType="Default">Log In</Button>
</form>
<Button
clicked={(event) => submitHandler(event, true)}
disabled={!formIsValid}
btnType="Link">Sign Up</Button>
</>
)
if (props.loading) {
form = <Spinner />
}
const errorMessage = props.error ? (
<div>
<p style={{ color: "red" }}>{props.error}</p>
</div>
) : null;
let authRedirect = null;
if (props.isAuthenticated) {
authRedirect = <Redirect to={'/'} />
}
return (
<main className={styles.Auth}>
{authRedirect}
<div className={styles.AuthForm}>
<h1>Log in to your account</h1>
<Logo height="3em" />
{errorMessage}
{form}
</div>
</main>
)
}
const mapStateToProps = (state) => {
return {
loading: state.auth.loading,
error: state.auth.error,
isAuthenticated: state.auth.token !== null,
}
}
const mapDispatchToProps = (dispatch) => {
return {
onAuth: (email, password, isSignup) => dispatch(authAction(email, password, isSignup))
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Auth)
我的测试:
import React from 'react';
import { Redirect } from 'react-router-dom';
import thunk from 'redux-thunk';
import { configure, shallow } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import configureStore from 'redux-mock-store';
import Auth from './Auth';
import Spinner from '../../components/UI/Spinner/Spinner';
import Button from '../../components/UI/Button/Button';
import Input from '../../components/UI/Input/Input';
configure({ adapter: new Adapter() });
const setup = () => {
const props = {
onAuth: jest.fn()
}
const middlewares = [thunk]
const mockStore = configureStore(middlewares);
const initialState = {
auth: {
token: null,
email: null,
error: null,
loading: false
}
};
const store = mockStore(initialState);
const enzymeWrapper = shallow(<Auth store={store} {...props} />).dive();
return {
enzymeWrapper,
props,
store
}
}
describe('<Auth />', () => {
it('should calls onSubmit prop function when form is submitted', () => {
const { enzymeWrapper: wrapper, props: reduxProps, store } = setup();
const form = wrapper.find('form');
form.simulate('submit', {
preventDefault: () => { }
});
expect(wrapper.props().onAuth).toHaveBeenCalled();
});
});
答案 0 :(得分:1)
要在没有存储连接的情况下测试 const pc = new RTCPeerConnection(configuration)
call.onclick = async () => {
localVideo.srcObject = await navigator.mediaDevices.getUserMedia({
video: true,
audio: true
});
for (const track of localVideo.srcObject.getTracks()) {
pc.addTrack(track, localVideo.srcObject);
}
};
pc.ontrack = e => remoteVideo.srcObject = e.streams[0];
pc.oniceconnectionstatechange = e => console.log(pc.iceConnectionState);
pc.onicecandidate = (e) => {
socket.emit('candidate', {
candidate: e.candidate
})
}
pc.onnegotiationneeded = async e => {
await pc.setLocalDescription(await pc.createOffer());
socket.emit('sdp', {
sdp: pc.localDescription
});
}
socket.on('data', (data) => {
if (data.sdp) {
pc.setRemoteDescription(new RTCSessionDescription(data.sdp));
if (data.sdp.type == "offer") {
pc.setLocalDescription(pc.createAnswer());
socket.emit('sdp', {
sdp: pc.localDescription
})
}
} else if (data.candidate) {
pc.addIceCandidate(new RTCIceCandidate(data.candidate))
}
})
类,您需要使用命名的import而不是默认的import。 PFB该行添加到您的测试文件中以导入Auth组件:
socket.on('sdp', function(data) {
socket.broadcast.emit('data',{sdp: data.sdp});
});
socket.on('candidate', function(data) {
socket.broadcast.emit('data',{candidate: data.candidate});
});
此外,通过这种方法,您无需在渲染时将存储作为道具传递给组件,而可以将动作作为模拟函数传递(您已经在进行Auth
动作了)。您也可以通过这种方法使用浅表。