I am trying to test my SEO component which looks like this:
JavaScript
x
19
19
1
export const Seo: React.FC<Props> = ({ seo, title, excerpt, heroImage }) => {
2
const description = seo?.description || excerpt
3
const pageTitle = seo?.title || title
4
5
const router = useRouter()
6
7
return (
8
<NextSeo // https://www.npmjs.com/package/next-seo
9
canonical={seo?.canonical}
10
nofollow={seo?.nofollow}
11
noindex={seo?.noindex}
12
title={pageTitle}
13
description={description}
14
openGraph={{
15
title,
16
description,
17
type: "article",
18
19
and my test is like so:
JavaScript
1
33
33
1
describe("Seo", () => {
2
it("should render the meta tags", async () => {
3
const props = {
4
title: "title page",
5
excerpt: "string",
6
seo: {
7
title: "seo title",
8
description: "meta description",
9
},
10
heroImage: {
11
src: "url",
12
alt: "alt text",
13
width: 300,
14
height: 400,
15
},
16
}
17
18
function getMeta(metaName: string) {
19
const metas = document.getElementsByTagName("meta")
20
for (let i = 0; i < metas.length; i += 1) {
21
if (metas[i].getAttribute("name") === metaName) {
22
return metas[i].getAttribute("content")
23
}
24
}
25
return ""
26
}
27
28
render(<Seo {props} />)
29
30
await waitFor(() => expect(getMeta("title")).toEqual("title page"))
31
})
32
})
33
however the test is failing: (it looks like the head element is empty)
Advertisement
Answer
I was having the same issue, but I found this answer on GitHub.
So basically you need to mock next/head
, pass document.head
to the container property of render
‘s options and finally access the document
.
Your test would end up like this:
JavaScript
1
32
32
1
jest.mock('next/head', () => {
2
return {
3
__esModule: true,
4
default: ({ children }: { children: Array<React.ReactElement> }) => {
5
return <>{children}</>;
6
},
7
};
8
});
9
10
describe("Seo", () => {
11
it("should render the meta tags", () => {
12
const props = {
13
title: "title page",
14
excerpt: "string",
15
seo: {
16
title: "seo title",
17
description: "meta description",
18
},
19
heroImage: {
20
src: "url",
21
alt: "alt text",
22
width: 300,
23
height: 400,
24
},
25
}
26
27
render(<Seo {props} />, { container: document.head })
28
29
expect(document.title).toBe("title page")
30
})
31
})
32
In my case I didn’t test it with that getMeta
function but I believe it would work too.