首页 > 解决方案 > Can you have complete coverage when using the pure component pattern to test Gatsby's static queries?

问题描述

According to Gatsby docs, components that use static queries need to be split into variants: one being a pure component and the other that actually uses the static query, passing results to the pure component.

Given an example component:

import React from "react";
import { Helmet } from "react-helmet";
import { useStaticQuery, graphql } from "gatsby";

export const PureSEO = ({
  description = ``,
  lang = `en`,
  meta = [],
  title = ``,
  image = ``,
  ...metaData
}): JSX.Element => {
  const metaDescription = description;

  return (
    <Helmet
      htmlAttributes={{
        lang,
      }}
      title={title}
      titleTemplate={`%s | ${title}`}
      meta={[
        {
          name: `description`,
          content: metaDescription,
        },
        {
          property: `og:title`,
          content: title,
        },
        {
          property: `og:description`,
          content: metaDescription,
        },
        {
          property: `og:type`,
          content: `website`,
        },
        {
          name: `twitter:card`,
          content: `summary`,
        },
        {
          name: `twitter:creator`,
          content: metaData.author,
        },
        {
          name: `twitter:title`,
          content: title,
        },
        {
          name: `twitter:description`,
          content: metaDescription,
        },
        {
          name: `og:image`,
          content: image,
        },
        {
          name: `twitter:image`,
          content: image,
        },
        {
          name: `image`,
          content: image,
        },
      ].concat(meta)}
    />
  );
};

const SEO: React.FC<Props> = ({
  description = ``,
  lang = `en`,
  meta = [],
  title = ``,
}): JSX.Element => {
  const { site, image } = useStaticQuery(
    graphql`
      query {
        site {
          siteMetadata {
            title
            description
            author
            rootDir
          }
        }
        image: file(relativePath: { eq: "favicon.png" }) {
          childImageSharp {
            fixed(width: 400) {
              ...GatsbyImageSharpFixed
            }
          }
        }
      }
    `
  );

  return (
    <PureSEO
      {...site.siteMetadata}
      description={description}
      image={image}
      lang={lang}
      meta={meta}
      title={title}
    />
  );
};

interface Props {
  description?: string;
  lang?: string;
  meta?: HTMLMetaElement[];
  title: string;
}

export default SEO;

I don't get full test coverage because SEO is not tested; but I don't think I should be testing that component, since the only logical difference is that it is using static queries.

How can I achieve better or 100% test coverage for my components, given this pattern?

标签: javascriptreactjstestinggatsby

解决方案


这个问题与您如何对与某种外部服务(例如 SQL 数据库)通信的后端组件进行单元测试非常相似。

你当然可以模拟useStaticQuery它会给你更高的覆盖率,但它实际上不会让你更确定你的代码可以工作。您要测试的内容围绕 GraphQL 查询的正确性以及响应格式是否符合您的预期,这不是您可以单元测试的内容。

因此,如果您想确定您的代码是否有效,您需要执行集成测试,例如通过针对已构建网站运行赛普拉斯测试。

从理论上讲,您还可以使用合同测试来检查您的查询本身是否按预期执行,但对于这个用例来说,这似乎是一个不必要的复杂解决方案。


推荐阅读