我建立了一个自定义挂钩,我想从中建立测试,但我不知道从哪里开始,我希望您能帮助我解释一些事情:
1。我如何在测试中捕捉鼠标 2.如何使用useRef并将其关联为当前值 如果您可以帮助我并向我展示代码,这将非常有帮助,因为有时我会坐在上面
下面是自定义钩子,我在其中实现了自定义钩子的代码 预先感谢?
unix
这是使用它的组件:
import { useEffect } from 'react';
function useOnClickOutside(ref, callback) {
useEffect(
() => {
const listener = (event) => {
// Do nothing if clicking ref's element or descendent elements
if (!ref.current || ref.current.contains(event.target)) {
return;
}
callback(event);
};
document.addEventListener('mousedown', listener);
document.addEventListener('touchstart', listener);
return () => {
document.removeEventListener('mousedown', listener);
document.removeEventListener('touchstart', listener);
};
},
[ref, callback],
);
}
export default useOnClickOutside;
答案 0 :(得分:0)
我为您的案例找到了不错的博客文章。这里有如何测试onClickOutside https://webman.pro/blog/how-to-detect-and-test-click-outside-in-react/的信息 我查看了您的组件,并对它的实际工作方式产生了好奇。)因此,如果您添加了示例代码,我会为您提供更多帮助)
更新 我在您的组件中添加了内容的测试ID) 组件:
import React, { useRef } from "react";
import ReactDOM from "react-dom";
import styles from "./OverlayDialog.module.css";
import useOnClickOutside from "./useOnClickOutside";
const OverlayDialog = (props) => {
const wrapperRef = useRef(null);
useOnClickOutside(wrapperRef, () => props.onClose());
return ReactDOM.createPortal(
<div className={styles.Dialog}>
<div className={styles.InnerDialog} tabIndex={1}>
<div className={styles.DialogCard} tabIndex={-1}>
<div
className={props.className ? props.className : styles.DialogContent}
ref={wrapperRef}
data-testid="content"
>
{props.children}
</div>
</div>
</div>
</div>,
document.getElementById("OverlayDialog")
);
};
export default OverlayDialog;
测试:
import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import OverlayDialog from "./OverlayDialog";
test('renders learn react link', () => {
const onClose = jest.fn();
const modalRoot = document.createElement('div');
modalRoot.setAttribute('id', 'OverlayDialog');
const body = document.querySelector('body');
body.appendChild(modalRoot);
render(
<OverlayDialog onClose={onClose}>
content
</OverlayDialog>
);
/*checking that if we click on content nothing happens*/
expect(screen.queryByTestId('content')).toBeInTheDocument();
fireEvent(screen.queryByTestId('content'), new MouseEvent('mousedown', {
bubbles: true,
cancelable: true,
}));
expect(onClose).not.toBeCalled();
/*checking that if we click outside we'll fire onClose*/
fireEvent(body, new MouseEvent('mousedown', {
bubbles: true,
cancelable: true,
}));
expect(onClose).toBeCalled();
});
答案 1 :(得分:0)
单独测试 useOnClickOutside 的示例
import logo from './logo.svg';
import './App.css';
import React, { useState } from "react";
function App() {
const [newWager, setWager] = useState(0);
const [userSide, setUserSide] = useState(0);
const [retrievedSide1, setRetrievedSide1] = useState("1");
const [retrievedSide2, setRetrievedSide2] = useState("2");
const wager = async (t) => {
if(t) { t.preventDefault(); }
else { console.log('No t') };
let str = newWager + ' on side ' + userSide;
wagerComplete(str);
let form = document.getElementById("submitWagerForm");
form.reset();
};
const wagerComplete = async (wagerstr) => {
console.log(wagerstr);
alert(wagerstr);
};
const beginRound = async (t) => {
t.preventDefault();
// setRetrievedSide1(document.getElementById("side1").value);
// setRetrievedSide2(document.getElementById("side2").value);
try{
// const accounts = await window.ethereum.enable();
// const account = accounts[0];
// const gas = await eventWagerContract.methods.beginRound(retrievedSide1, retrievedSide2).estimateGas();
// const post = await eventWagerContract.methods.beginRound(retrievedSide1, retrievedSide2).send({ from: account, gas });
alert(retrievedSide1 + ' ' + retrievedSide2);
wager();
}
catch(e)
{
alert('Apparently this is the best way to display blockchain errors :/\n\n' + e.message);
}
let form = document.getElementById("beginRoundForm");
form.reset();
};
return (
<div className="App">
<form className="form" id="submitWagerForm" autocomplete="off" onSubmit={wager}>
<label>
Enter your wager and side:
<br />
<input
className="input"
type="text"
name="amount"
placeholder="# of WC"
onChange={(t) => setWager(t.target.value)}
/>
<input
className="input"
type="text"
name="side"
placeholder="1 or 2"
onChange={(t) => setUserSide(t.target.value)}
/>
</label>
<button className="button" type="submit" value="Submit">
Submit
</button>
</form>
<form className="form" id="beginRoundForm" autocomplete="off" onSubmit={beginRound}>
<label>
<input
className="input"
type="text"
name="name"
id="side1"
placeholder="Side 1"
onChange={(t) => setRetrievedSide1(t.target.value)}
/>
<input
className="input"
type="text"
name="side"
placeholder="Side 2"
id="side2"
onChange={(t) => setRetrievedSide2(t.target.value)}
/>
<button className="button" type="submit" value="Submit">
Begin Round
</button>
</label>
</form>
</div>
);
}
export default App;