如何在React组件测试中使用data-testid属性?

huangapple go评论127阅读模式
英文:

How do I use data-testid attribute with a React Component Test?

问题

I am doing a Component Test on a simple react component, which I want to render and then do some tests on.

The problem is that cy.get() does not seem to find the component based on a data-testid attribute.

I tested it with a simple div and the div can be found just fine.

I also noticed when inspecting the DOM in the cypress runner, that the Component is not being rendered, but the contents of it are. Basically there is no <MockComponent>

  it.only("renders and finds Component", () => {
    cy.mount(
      <ApolloProvider client={client}>
        <MockComponent data-testid='mock-component' {...someData} />
        <div data-testid='my-div'></div>
      </ApolloProvider>
    );

    cy.get("[data-testid='my-div']").should('exist'); //this works
    cy.get("[data-testid='mock-component']").should('exist'); //this doesn't

  });

How can I get the <MockComponent> in cypress, so that I can run tests on it?

英文:

I am doing a Component Test on a simple react component, which I want to render and then do some tests on.

The problem is that cy.get() does not seem to find the component based on a data-testid attribute.

I tested it with a simple div and the div can be found just fine.

I also noticed when inspecting the DOM in the cypress runner, that the Component is not being rendered, but the contents of it are. Basically there is no &lt;MockComponent&gt;

  it.only(&quot;renders and finds Component&quot;, () =&gt; {
    cy.mount(
      &lt;ApolloProvider client={client}&gt;
        &lt;MockComponent data-testid=&#39;mock-component&#39; {...someData} /&gt;
        &lt;div data-testid=&#39;my-div&#39;&gt;&lt;/div&gt;
      &lt;/ApolloProvider&gt;
    );

    cy.get(&quot;[data-testid=&#39;my-div&#39;]&quot;).should(&#39;exist&#39;); //this works
    cy.get(&quot;[data-testid=&#39;mock-component&#39;]&quot;).should(&#39;exist&#39;); //this doesn&#39;t

  });

How can I get the &lt;MockComponent&gt; in cypress, so that I can run tests on it?

答案1

得分: 6

以下是您要翻译的内容:

You can't add data-id attributes directly to the React component and have it appear on the DOM content.

All attributes (data or otherwise) that you put on MockComponent are passed in as props to your component. This is standard for React.

So, if you examine props inside MockComponent, it will have a property named data-testid with a value of mock-component.

You will have to convert that into an attribute inside MockComponent, on one of it's rendered elements.

Note that MockComponent never appear in the DOM, just it's rendered children.

For example, explicitly:

const MockComponent = (props) => {
  return (
    <div data-testid={props["data-testid"]}>    
      <span>this is mock component</span>
    </div>
  )
}

...

cy.get("[data-testid='mock-component']")   // passes

The <div> inside MockComponent's return value is the "outer" element rendered to DOM, so that's where you need the data-id.


Or you can do it implicitly. Since someData is part of your component API, you can split it off and assume the remainder will be utilized as attributes (without actually knowing what they are).

const MockComponent = (props) => {
  const { someData, ...rest } = props;

  const [data, setData] = useState(someData);

  return (
    <div {...rest}>
      <span>this is mock component</span>
    </div>
  )
}

...

cy.get("[data-testid='mock-component']")   // passes

One more way is to add a child to MockComponent, which must be a real element.

All child elements are passed as props.children, and you must render them inside the return value.

const MockComponent = (props) => {
  const { someData } = props;

  const [data, setData] = useState(someData);

  return (
    <div>
      <span>this is mock component</span>
      {props.children}
    </div>
  )
}

...

cy.mount(
  <MockComponent {...someData} >
    <span data-testid='mock-component-child' ></span>
  </MockComponent>
);

cy.get("[data-testid='mock-component-child']")   // passes
  .parent()                              // outer element of MockComponent
英文:

You can't add data-id attributes directly to the the React component and have it appear on the DOM content.

All attributes (data or otherwise) that you put on MockComponent are passed in as props to your component. This is standard for React.

So, if you examine props inside MockComponent, it will have a property named data-testid with a value of mock-component.

You will have to convert that into an attribute inside MockComponent, on one of it's rendered elements.

Note that MockComponent never appear in the DOM, just it's rendered children.

For example, explicitly:

const MockComponent = (props) =&gt; {
  return (
    &lt;div data-testid={props[&quot;data-testid&quot;]}&gt;    
      &lt;span&gt;this is mock component&lt;/span&gt;
    &lt;/div&gt;
  )
}

...

cy.get(&quot;[data-testid=&#39;mock-component&#39;]&quot;)   // passes

The &lt;div&gt; inside MockComponent's return value is the "outer" element rendered to DOM, so that's where you need the data-id.


Or you can do it implicitly. Since someData is part of your component API, you can split it off and assume the remainder will be utilized as attributes (without actually knowing what they are).

const MockComponent = (props) =&gt; {
  const {someData, ...rest} = props;

  const [data, setData] = useState(someData);

  return (
    &lt;div {...rest}&gt;
      &lt;span&gt;this is mock component&lt;/span&gt;
    &lt;/div&gt;
  )
}

...

cy.get(&quot;[data-testid=&#39;mock-component&#39;]&quot;)   // passes

One more way is to add a child to MockComponent, which must be a real element.

All child elements are passed as props.children, and you must render them inside the return value.

const MockComponent = (props) =&gt; {
  const {someData} = props

  const [data, setData] = useState(someData);

  return (
    &lt;div&gt;
      &lt;span&gt;this is mock component&lt;/span&gt;
      {props.children}
    &lt;/div&gt;
  )
}

...

cy.mount(
  &lt;MockComponent {...someData} &gt;
    &lt;span data-testid=&#39;mock-component-child&#39; &gt;&lt;/span&gt;
  &lt;/MockComponent&gt;
);

cy.get(&quot;[data-testid=&#39;mock-component-child&#39;]&quot;)   // passes
  .parent()                              // outer element of MockComponent

huangapple
  • 本文由 发表于 2023年3月7日 16:59:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/75659831.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定