[javascript] JEST 테스트에서 getComputedStyle ()이 Chrome / Firefox DevTools의 계산 된 스타일에 다른 결과를 반환하는 이유
material-uiMyStyledButton
기반 사용자 정의 버튼 ( )을 작성했습니다 . Button
import React from "react";
import { Button } from "@material-ui/core";
import { makeStyles } from "@material-ui/styles";
const useStyles = makeStyles({
root: {
minWidth: 100
}
});
function MyStyledButton(props) {
const buttonStyle = useStyles(props);
const { children, width, ...others } = props;
return (
<Button classes={{ root: buttonStyle.root }} {...others}>
{children}
</Button>
);
}
export default MyStyledButton;
테마를 사용하여 스타일이 지정 backgroundColor
되며을 노란색 음영으로 지정합니다 (특히 #fbb900
)
import { createMuiTheme } from "@material-ui/core/styles";
export const myYellow = "#FBB900";
export const theme = createMuiTheme({
overrides: {
MuiButton: {
containedPrimary: {
color: "black",
backgroundColor: myYellow
}
}
}
});
구성 요소가 내 메인에서 인스턴스화 index.js
되고에 래핑됩니다 theme
.
<MuiThemeProvider theme={theme}>
<MyStyledButton variant="contained" color="primary">
Primary Click Me
</MyStyledButton>
</MuiThemeProvider>
Chrome DevTools에서 버튼을 검사하면 background-color
예상대로 “계산됩니다”. Firefox DevTools에서도 마찬가지입니다.
나는 농담 테스트를 작성할 때 그러나를 확인 background-color
하고 내가 사용하는 버튼의 DOM 노드 스타일을 쿼리 getComputedStyles()
내가 가져 transparent
왔다 테스트가 실패합니다.
const wrapper = mount(
<MyStyledButton variant="contained" color="primary">
Primary
</MyStyledButton>
);
const foundButton = wrapper.find("button");
expect(foundButton).toHaveLength(1);
//I want to check the background colour of the button here
//I've tried getComputedStyle() but it returns 'transparent' instead of #FBB900
expect(
window
.getComputedStyle(foundButton.getDOMNode())
.getPropertyValue("background-color")
).toEqual(myYellow);
정확한 문제, 재현 할 수있는 최소 코드 및 실패한 JEST 테스트가있는 CodeSandbox를 포함 시켰습니다.
답변
나는 더 가까워졌지만 아직 해결책이 없습니다.
주요 문제는 MUIButton이 요소에 태그를 삽입하여 스타일을 강화한다는 것입니다. 이것은 단위 테스트에서 일어나지 않습니다. 재료 테스트에서 사용 하는 createMount 를 사용하여이 작업을 수행 할 수있었습니다 .
이 수정 후 스타일이 올바르게 표시됩니다. 그러나 계산 된 스타일은 여전히 작동하지 않습니다. 다른 사람들이 효소를 올바르게 처리하는 데 문제가있는 것처럼 보입니다. 그래서 가능한지 확실하지 않습니다.
내가 어디를 얻으려면, 테스트 조각을, 정상에이를 복사 한 다음 테스트 코드를 변경 :
const myMount = createMount({ strict: true });
const wrapper = myMount(
<MuiThemeProvider theme={theme}>
<MyStyledButton variant="contained" color="primary">
Primary
</MyStyledButton>
</MuiThemeProvider>
);
class Mode extends React.Component {
static propTypes = {
/**
* this is essentially children. However we can't use children because then
* using `wrapper.setProps({ children })` would work differently if this component
* would be the root.
*/
__element: PropTypes.element.isRequired,
__strict: PropTypes.bool.isRequired,
};
render() {
// Excess props will come from e.g. enzyme setProps
const { __element, __strict, ...other } = this.props;
const Component = __strict ? React.StrictMode : React.Fragment;
return <Component>{React.cloneElement(__element, other)}</Component>;
}
}
// Generate an enhanced mount function.
function createMount(options = {}) {
const attachTo = document.createElement('div');
attachTo.className = 'app';
attachTo.setAttribute('id', 'app');
document.body.insertBefore(attachTo, document.body.firstChild);
const mountWithContext = function mountWithContext(node, localOptions = {}) {
const strict = true;
const disableUnnmount = false;
const localEnzymeOptions = {};
const globalEnzymeOptions = {};
if (!disableUnnmount) {
ReactDOM.unmountComponentAtNode(attachTo);
}
// some tests require that no other components are in the tree
// e.g. when doing .instance(), .state() etc.
return mount(strict == null ? node : <Mode __element={node} __strict={Boolean(strict)} />, {
attachTo,
...globalEnzymeOptions,
...localEnzymeOptions,
});
};
mountWithContext.attachTo = attachTo;
mountWithContext.cleanUp = () => {
ReactDOM.unmountComponentAtNode(attachTo);
attachTo.parentElement.removeChild(attachTo);
};
return mountWithContext;
}