У меня есть общий вопрос о работе с элементами DOM в библиотеке React Testing.
По сути, у меня есть несколько вложенных компонентов, один из которых создает ссылку React, которая пересылается некоторым дочерним компонентам (код ниже).
Когда он это делает, он затем визуализирует дочерние компоненты и проверяет вложенную ссылку для вызова .getBoundingClientRect()
волшебной собственной функции Javascript, которая дает мне позиционирование по x и y, ширину и высоту, а также верхнюю, нижнюю, левую и правую границы. Мне действительно нужна эта информация, потому что я хочу делать с ней другие вещи, не изменяя напрямую DOM (я делаю все свои модификации DOM с помощью setState и позволяю React повторно визуализировать DOM)
В разработке (Chrome), когда я делаю console.log(this.thing_one_ref.current.getBoundingClientRect())
, я получаю следующий результат:
(вы заметите, что thing_one_ref здесь правильно заполняется после рендеринга моего приложения - не раньше - и выглядит так :)
У меня есть простая спецификация для этого кода, который проходит успешно, но, несмотря на то, что он проходит, вывод журнала в тестовой среде выглядит следующим образом:
Обратите внимание, что все значения равны 0, а не то, что я ожидал, а именно элемент, который будет отображаться, как если бы он был в реальной DOM.
// src / App.test.js
import React from 'react';
import { render, wait } from '@testing-library/react';
import App from './App';
test('renders learn react link', async () => {
const { getByText, getByTestId } = render(<App />);
const linkElement = getByTestId("app")
await wait(() => expect(getByText(/A Test of refs/i, linkElement)).toBeInTheDocument());
});
// src / App.js
import React from 'react';
import './App.css';
import styled from 'styled-components'
import ThingOne from './thing_one'
import Container from './container'
const StyledApp = styled.div`
position: relative;
height: 100vh;
width: 100%;
`
function App() {
return (
<StyledApp data-testid="app" className="App" style={{position: 'relative'}}>
<Container />
</StyledApp>
);
}
export default App;
// src / container.js
import React from 'react'
import styled from 'styled-components'
import ThingOne from "./thing_one";
const StyledContainer = styled.div`
display: block;
`
class Container extends React.Component {
constructor(props) {
super(props)
this.thing_one_ref = React.createRef()
this.state = {
message: ""
}
}
componentDidMount() {
setTimeout(() => {
this.setState({message: "A test of refs"})
// here's the console.log
console.log(this.thing_one_ref.current.getBoundingClientRect())
}, 1000)
}
render() {
const {message} = this.state
return (
<StyledContainer>
{message}
<ThingOne ref={this.thing_one_ref}/>
</StyledContainer>
)
}
}
export default Container
// src / thing_one.js
import React from 'react'
import styled from 'styled-components'
const StyledThingOne = styled.div`
display: block;
width: 100px;
height: 100px;
position: relative;
top: 20%;
left: 20%;
border: solid 1px black;
margin: 20px;
`
const ThingOne = React.forwardRef((props, ref) => (
<StyledThingOne ref={ref}></StyledThingOne>
));
export default ThingOne
Как заставить тестовую среду вести себя так, как если бы она смонтирована в реальной модели DOM с декартовой плоскостью, которую я могу использовать для тригонометрии и анимации ? У меня есть рабочий код, который зависит от результата getBoundingClientRect()
, который выглядит примерно так (как сказано выше, работает в браузере)
DOMRect {x: 225.1875, y: 38, width: 102, height: 102, top: 38, …}
Полный исходный код можно найти здесь: