The Testing Components with GraphQL guide is outdated since the Gatsby Default Starter switched to useStaticQuery.
When a learner wants to get started with testing Gatsby, the first step is to go through the Unit Testing guide. The guide is essentially a walk-through of the required setup and config to get started with Jest (custom config, mocks, etc.).
The next step is to learn about Testing Components with GraphQL. This guides builds on the previous one and adds specs to test Gatsby StaticQuery queries.
The issue is that the example site being tested is the gatsby-starter-default, which doesn't have any StaticQuery queries since it switched entirely to the newer useStaticQuery.
Testing useStaticQuery is a little bit different from testing StaticQuery. An example can be found online at Mock Gatsby's useStaticQuery with Jest.
_Note: a recent PR (#18202) already added a note about testing 霉seStaticQuery somewhere further in the guide_
Updating the guide would further help people learn how to test Gatsby, and remove the frustration of following a guide and getting unexpected errors.
It seems that there are two possible paths to solving this issue:
gatsby-starter-default. In this case, the sections about testing StaticQuery wouldn't belong in this guide anymoreexamples/using-tests-for-graphql) that includes both StaticQuery and useStaticQuery and rewrite the guide to explain how to test both methodsI burnt a bit of time on this as well - after finding this issue and reading the linked page, I sorted out that I could add the jest.fn().mockImplementation inside of the __mocks__/gatsby.js file. This pulls in a fixtures file and returns the all the site query data inside of that. Care will need to be taken to make sure the fixtures / queries have unique names, but it should solve my issue (and maybe others)
This is what my __mocks__/gatsby.js now looks like:
import React from 'react';
import fixtures from '../src/___test___/fixtures';
const gatsby = jest.requireActual('gatsby');
module.exports = {
...gatsby,
graphql: jest.fn(),
Link: jest.fn().mockImplementation(
// these props are invalid for an `a` tag
({
activeClassName,
activeStyle,
getProps,
innerRef,
partiallyActive,
ref,
replace,
to,
...rest
}) =>
React.createElement('a', {
...rest,
href: to,
}),
),
StaticQuery: jest.fn(),
// useStaticQuery: jest.fn(),
useStaticQuery: jest.fn().mockImplementation(() => ({ ...fixtures })),
};
Thoughts on this approach?
Hiya!
This issue has gone quiet. Spooky quiet. 馃懟
We get a lot of issues, so we currently close issues after 30 days of inactivity. It鈥檚 been at least 20 days since the last update here.
If we missed this issue or if you want to keep it open, please reply here. You can also add the label "not stale" to keep this issue open!
As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request. Check out gatsby.dev/contribute for more information about opening PRs, triaging issues, and contributing!
Thanks for being a part of the Gatsby community! 馃挭馃挏
@robinmetral I'm not so sure about that Mocking example you linked. The author is setting up spies and doesn't provide a complete example. Searching GH I already see 109 instances of that pattern and many seem to be doing it differently. On top of that I don't see the author explaining spies/mocks may need to be reset in a teardown of some sort such as afterEach.
I feel at a minimum the takeaway here is that Gatsby's using-jest example _should be_ updated to show a specific example of testing with useStaticQuery _especially_ given it's the method provided now in the default starter as you mention. Perhaps using a composition library such as the one I mention in a related issue or, possibly better yet, using react-hooks-testing-library as shown here.
EDIT Article updated spies example with feedback.
I just ran into that issue too. This is really confusing, especially as a beginner to Gatsby.
Thankfully this issue exists and pointed me in the right direction. I was able to adjust the test from StaticQuery to useStaticQuery (which is actually used in the components created by the current starter template).
In case anybody else is running into this issue while learning, I was able to redefine the test like so:
/* eslint-env jest */
import React from 'react'
import renderer from 'react-test-renderer'
import { useStaticQuery } from 'gatsby'
import Index from '../index'
beforeEach(() => {
useStaticQuery
.mockImplementationOnce(() => { // Mock for use in Layout
return {
site: {
siteMetadata: {
title: 'Gatsby Default Starter'
}
}
}
})
.mockImplementationOnce(() => { // Mock for use in SEO
return {
site: {
siteMetadata: {
title: 'Gatsby Default Starter',
description: 'Kick off your next, great Gatsby project with this default starter. This barebones starter ships with the main Gatsby configuration files you might need.',
author: '@gatsbyjs'
}
}
}
})
.mockImplementationOnce(() => { // Mock for use in Image
return {
placeholderImage: {
childImageSharp: {
fluid: {
base64: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAIAAAAC64paAAAACXBIWXMAAAsSAAALEgHS3X78AAACYklEQVQ4y42Uy28SQRjA+dM8efDmwYN6qF6qiSY+Y/WgQRMibY00TaWNBSRSCraYQtHl/bR0KyxQWCgWWAqU8izl/Sq7rLNsRHlVJpvJtzPfb77nDIOcZHSoqZSrp4+KtXIziubaLRysMCZiCYqOoVnhjNEi8RcztdxxeTzc6VBfT+5O2Vhpb+vw4wMdZ0ppWvP9xzLeJoDNThf2W+Nz1+XzNxQubSToSKKW+BDc+WOnkshhSVgeCiGpViZMEg1oxc26Knt+ae3bEtJTZwzE1kXLccG0+sOOlrcvZXvsczPkITfsa20vwIKnhsh+BnjUarT74Gb13CY7KBVJMv3z4N1NszQYsMWM62HNrCis/GxXn0iYls23uz5LPBcv0bH8hUH2XRoM85ySXv7JBtO87jMIvWq+H5GoYIHCLA1ZxD6Qap3Ak8IKfW7TJ50lK6uP9E6RgndHaODtCJ6Z5RyHfnE7j6gRbcKlCYNSt+rtETHTpUGgEP8FYmdNqd/Mo7aiVWTfuH2L9xASvfxxlqr01EYkrJszvNkgW9bH0OuFr+99m+y9IOeyU6zIp/Hubp/yMEztlzFPwOhdvq+nIoS1JNn4t2sugCmVsDvPe2KKolnZLCxhOcAKQRDDXTQaVi46lqYhIBwHTrl3oWqhMRDtaJge37lOBMKo4tfbqhVX0J7snTsWps8uZWuoOQY6CcjpSIF55UvmqNgr5wUwtV1IVdnXtnSfPEB2qjDNqnvczRl0m+j6Jn5lXb6nAQJqinmN0ZEBj03YLzghY8PnTRz80o/GRJZpOLCb0PM9BN7pvUEjx28V00WUg9jIVwAAAABJRU5ErkJggg==',
aspectRatio: 1,
src: '/static/6d91c86c0fde632ba4cd01062fd9ccfa/630fb/gatsby-astronaut.png',
srcSet: '/static/6d91c86c0fde632ba4cd01062fd9ccfa/5db04/gatsby-astronaut.png 75w,\n/static/6d91c86c0fde632ba4cd01062fd9ccfa/6d161/gatsby-astronaut.png 150w,\n/static/6d91c86c0fde632ba4cd01062fd9ccfa/630fb/gatsby-astronaut.png 300w,\n/static/6d91c86c0fde632ba4cd01062fd9ccfa/62b1f/gatsby-astronaut.png 450w,\n/static/6d91c86c0fde632ba4cd01062fd9ccfa/2a4de/gatsby-astronaut.png 600w,\n/static/6d91c86c0fde632ba4cd01062fd9ccfa/ee604/gatsby-astronaut.png 800w',
sizes: '(max-width: 300px) 100vw, 300px'
}
}
}
}
})
})
describe('Index', () => {
it('renders correctly', () => {
const tree = renderer.create(<Index />).toJSON()
expect(tree).toMatchSnapshot()
})
})
To get the returned mock data, I went to http://localhost:8000/___graphql and ran the queries that are defined in each component (Layout, SEO and Image). For the image component, the ...GatsbyImageSharpFluid fragment needs to be replaced with
aspectRatio
src
srcSet
sizes
This is already suggested on the docs page in question.
The fact that I am mocking the same function three times is probably not the most elegant, but it solved my issue without getting into many other issues. The issue is that the function that needs to mocking is used in many place when testing a whole page.
I guess a more elegant solution would be to mock the different components that are using the useStaticQuery and test these components in isolation elsewhere.
I just came across this issue also in evaluating Gatsby as a frontend framework for the agency I work for. It was frustrating to say the least for it be painful getting TDD setup.
I would be open to doing some work to implement the fixes you suggest @robinmetral?
Hey @mathewtrivett, I personally think this would be amazing, but maybe it would make sense to ask for opinions from the Gatsby learning team? I can't assign or tag them anymore, but as far as I can see they haven't been part of this discussion yet.
Another way might be to draft a PR for this already, it would make the discussion on specific points easier 馃檪 I think we all agree that we need better docs for this
Most helpful comment
I just ran into that issue too. This is really confusing, especially as a beginner to Gatsby.
Thankfully this issue exists and pointed me in the right direction. I was able to adjust the test from
StaticQuerytouseStaticQuery(which is actually used in the components created by the current starter template).In case anybody else is running into this issue while learning, I was able to redefine the test like so:
To get the returned mock data, I went to
http://localhost:8000/___graphqland ran the queries that are defined in each component (Layout,SEOandImage). For the image component, the...GatsbyImageSharpFluidfragment needs to be replaced withThis is already suggested on the docs page in question.
The fact that I am mocking the same function three times is probably not the most elegant, but it solved my issue without getting into many other issues. The issue is that the function that needs to mocking is used in many place when testing a whole page.
I guess a more elegant solution would be to mock the different components that are using the
useStaticQueryand test these components in isolation elsewhere.