Mengapa getComputedStyle () dalam tes JEST mengembalikan hasil yang berbeda ke gaya yang dihitung di Chrome / Firefox DevTools

16

Saya telah menulis tombol khusus ( MyStyledButton) berdasarkan material-ui 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;

Ini ditata menggunakan tema dan ini menentukan backgroundColoruntuk menjadi warna kuning (Khususnya #fbb900)

import { createMuiTheme } from "@material-ui/core/styles";

export const myYellow = "#FBB900";

export const theme = createMuiTheme({
  overrides: {
    MuiButton: {
      containedPrimary: {
        color: "black",
        backgroundColor: myYellow
      }
    }
  }
});

Komponen ini dipakai di main saya index.jsdan dibungkus dalam theme.

  <MuiThemeProvider theme={theme}>
     <MyStyledButton variant="contained" color="primary">
       Primary Click Me
     </MyStyledButton>
  </MuiThemeProvider>

Jika saya memeriksa tombol di Chrome DevTools background-color"dikomputasi" seperti yang diharapkan. Ini juga terjadi di Firefox DevTools.

Tangkapan layar dari Chrome

Namun ketika saya menulis tes JEST untuk memeriksa background-colordan saya meminta gaya simpul DOM jika tombol menggunakan getComputedStyles()saya transparentkembali dan tes gagal.

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);

Saya telah memasukkan CodeSandbox dengan masalah yang tepat, kode minimum untuk mereproduksi dan tes JEST yang gagal.

Edit headless-snow-nyofd

Simon Long
sumber
.MuiButtonBase-root-33 background-color transparan sementara .MuiButton-containedPrimary-13 tidak - jadi masalahnya adalah, kelas-kelas di CSS sama pentingnya, jadi hanya urutan beban membedakannya -> dalam gaya uji dimuat dalam urutan yang salah.
Zydnar
1
@ Andreas - Diperbarui sesuai permintaan
Simon Long
@ Zyndar - Ya saya tahu itu. Apakah ada cara untuk lulus tes ini?
Simon Long
Bukankah themeperlu digunakan dalam ujian? Seperti di, bungkus <MyStyledButton>dalam <MuiThemeProvider theme={theme}>? Atau gunakan beberapa fungsi pembungkus untuk menambahkan tema ke semua komponen?
Brett DeWoody
Tidak, itu tidak ada bedanya.
Simon Long

Jawaban:

1

Saya sudah semakin dekat, tetapi belum menemukan solusi.

Masalah utama adalah bahwa MUIButton menyuntikkan tag ke elemen untuk memberi gaya pada style. Ini tidak terjadi dalam pengujian unit Anda. Saya bisa menjalankan ini dengan menggunakan createMount yang menggunakan tes materi.

Setelah perbaikan ini, gaya ditampilkan dengan benar. Namun, gaya komputasi masih tidak berfungsi. Sepertinya orang lain mengalami masalah dengan penanganan enzim ini dengan benar - jadi saya tidak yakin apakah itu mungkin.

Untuk sampai ke tempat saya sebelumnya, ambil cuplikan pengujian Anda, salin ini ke atas, lalu ubah kode pengujian Anda ke:

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;
}
AnilRedshift
sumber