docs: fixes and improvements to testing docs (#11244)

* docs: fixes and improvements to testing docs

* generate files
This commit is contained in:
Shahed Nasser
2025-01-31 15:36:20 +02:00
committed by GitHub
parent 105e73b523
commit d6480c4d0a
12 changed files with 224 additions and 38 deletions
@@ -304,3 +304,66 @@ In the test, you use the `api.delete` method to send a `DELETE` request to `/cus
- Has a `success` property in its data.
- The `success` property's value is true.
---
## Pass Headers in Test Requests
Some requests require passing headers. For example, all routes prefixed with `/store` must pass a publishable API key in the header.
The `get`, `post`, and `delete` methods accept an optional third parameter that you can pass a `headers` property to, whose value is an object of headers to pass in the request.
For example, to pass a publishable API key in the header for a request to a `/store` route:
export const headersHighlights = [
["10", "pak", "Create a publishable API key before the tests run."],
["27", "headers", "Pass the publishable API key in the request's header."]
]
```ts title="integration-tests/http/custom-routes.spec.ts" highlights={headersHighlights}
import { medusaIntegrationTestRunner } from "@medusajs/test-utils"
import { ApiKeyDTO } from "@medusajs/framework/types"
import { createApiKeysWorkflow } from "@medusajs/medusa/core-flows"
medusaIntegrationTestRunner({
testSuite: ({ api, getContainer }) => {
describe("Custom endpoints", () => {
let pak: ApiKeyDTO
beforeAll(async () => {
pak = (await createApiKeysWorkflow(getContainer()).run({
input: {
api_keys: [
{
type: "publishable",
title: "Test Key",
created_by: ""
}
]
}
})).result[0]
})
describe("GET /custom", () => {
it("returns correct message", async () => {
const response = await api.get(
`/store/custom`,
{
headers: {
"x-publishable-api-key": pak.token
}
}
)
expect(response.status).toEqual(200)
expect(response.data).toHaveProperty("message")
expect(response.data.message).toEqual("Hello, World!")
})
})
})
},
})
jest.setTimeout(60 * 1000)
```
In your test suit, you add a `beforeAll` hook to create a publishable API key before the tests run. To create the API key, you can use the `createApiKeysWorkflow` or the [API Key Module's service](!resources!/commerce-modules/api-key).
Then, in the test, you pass an object as the last parameter to `api.get` with a `headers` property. The `headers` property is an object with the key `x-publishable-api-key` and the value of the API key's token.
@@ -93,3 +93,52 @@ If you don't have a `test:integration` script in `package.json`, refer to the [M
</Note>
This runs your Medusa application and runs the tests available under the `integrations/http` directory.
---
## Test That a Workflow Throws an Error
You might want to test that a workflow throws an error in certain cases. To test this:
- Disable the `throwOnError` option when executing the workflow.
- Use the returned `errors` property to check what errors were thrown.
For example, if you have a step that throws this error:
```ts title="src/workflows/hello-world.ts"
import { MedusaError } from "@medusajs/framework/utils"
import { createStep } from "@medusajs/framework/workflows-sdk"
const step1 = createStep("step-1", () => {
throw new MedusaError(MedusaError.Types.NOT_FOUND, "Item doesn't exist")
})
```
You can write the following test to ensure that the workflow throws that error:
```ts title="integration-tests/http/workflow.spec.ts"
import { medusaIntegrationTestRunner } from "@medusajs/test-utils"
import { helloWorldWorkflow } from "../../src/workflows/hello-world"
medusaIntegrationTestRunner({
testSuite: ({ getContainer }) => {
describe("Test hello-world workflow", () => {
it("returns message", async () => {
const { errors } = await helloWorldWorkflow(getContainer())
.run({
throwOnError: false
})
expect(errors.length).toBeGreaterThan(0)
expect(errors[0].error.message).toBe("Item doesn't exist")
})
})
},
})
jest.setTimeout(60 * 1000)
```
The `errors` property contains an array of errors thrown during the execution of the workflow. Each error item has an `error` object, being the error thrown.
If you threw a `MedusaError`, then you can check the error message in `errors[0].error.message`.
@@ -58,6 +58,8 @@ moduleIntegrationTestRunner<HelloModuleService>({
})
},
})
jest.setTimeout(60 * 1000)
```
You use the `moduleIntegrationTestRunner` function to add tests for the `hello` module. You have one test that passes if the `getMessage` method returns the `"Hello, World!"` string.
@@ -69,12 +71,12 @@ You use the `moduleIntegrationTestRunner` function to add tests for the `hello`
Run the following command to run your module integration tests:
```bash npm2yarn
npm run test:modules
npm run test:integration:modules
```
<Note title="Tip">
If you don't have a `test:modules` script in `package.json`, refer to the [Medusa Testing Tools chapter](../../page.mdx#add-test-commands).
If you don't have a `test:integration:modules` script in `package.json`, refer to the [Medusa Testing Tools chapter](../../page.mdx#add-test-commands).
</Note>
@@ -37,6 +37,8 @@ moduleIntegrationTestRunner<HelloModuleService>({
// TODO write tests
},
})
jest.setTimeout(60 * 1000)
```
The `moduleIntegrationTestRunner` function accepts as a parameter an object with the following properties:
@@ -63,12 +65,12 @@ The tests in the `testSuite` function are written using [Jest](https://jestjs.io
Run the following command to run your module integration tests:
```bash npm2yarn
npm run test:modules
npm run test:integration:modules
```
<Note title="Tip">
If you don't have a `test:modules` script in `package.json`, refer to the [Medusa Testing Tools chapter](../page.mdx#add-test-commands).
If you don't have a `test:integration:modules` script in `package.json`, refer to the [Medusa Testing Tools chapter](../page.mdx#add-test-commands).
</Note>
@@ -115,6 +117,8 @@ moduleIntegrationTestRunner<HelloModuleService>({
moduleModels: [DummyModel],
// ...
})
jest.setTimeout(60 * 1000)
```
---
@@ -22,14 +22,6 @@ npm install --save-dev @medusajs/test-utils@latest
Writing tests with `@medusajs/test-utils`'s tools requires installing and configuring Jest in your project.
{/* TODO remove this note at some point in the future */}
<Note>
If your Medusa project was created after September 3rd, Jest is already installed and configured.
</Note>
Run the following command to install the required Jest dependencies:
```bash npm2yarn
@@ -56,6 +48,7 @@ module.exports = {
testEnvironment: "node",
moduleFileExtensions: ["js", "ts", "json"],
modulePathIgnorePatterns: ["dist/"],
setupFiles: ["./integration-tests/setup.js"],
}
if (process.env.TEST_TYPE === "integration:http") {
@@ -67,6 +60,14 @@ if (process.env.TEST_TYPE === "integration:http") {
}
```
Next, create the `integration-tests/setup.js` file with the following content:
```js title="integration-tests/setup.js"
const { MetadataStorage } = require("@mikro-orm/core")
MetadataStorage.clear()
```
---
## Add Test Commands
+6 -7
View File
@@ -59,10 +59,10 @@ export const generatedEditDates = {
"app/learn/fundamentals/data-models/index/page.mdx": "2024-10-21T13:30:21.368Z",
"app/learn/fundamentals/custom-cli-scripts/page.mdx": "2024-10-23T07:08:55.898Z",
"app/learn/fundamentals/data-models/property-types/page.mdx": "2024-12-12T10:41:32.999Z",
"app/learn/debugging-and-testing/testing-tools/integration-tests/api-routes/page.mdx": "2024-12-09T15:34:08.049Z",
"app/learn/debugging-and-testing/testing-tools/integration-tests/api-routes/page.mdx": "2025-01-31T13:19:02.586Z",
"app/learn/debugging-and-testing/testing-tools/integration-tests/page.mdx": "2024-12-09T15:52:01.019Z",
"app/learn/debugging-and-testing/testing-tools/integration-tests/workflows/page.mdx": "2024-12-09T15:51:15.422Z",
"app/learn/debugging-and-testing/testing-tools/page.mdx": "2024-12-09T15:53:56.878Z",
"app/learn/debugging-and-testing/testing-tools/integration-tests/workflows/page.mdx": "2025-01-31T13:19:02.586Z",
"app/learn/debugging-and-testing/testing-tools/page.mdx": "2025-01-31T13:19:02.587Z",
"app/learn/debugging-and-testing/testing-tools/unit-tests/module-example/page.mdx": "2024-09-02T11:04:27.232Z",
"app/learn/debugging-and-testing/testing-tools/unit-tests/page.mdx": "2024-09-02T11:03:26.997Z",
"app/learn/fundamentals/modules/service-constraints/page.mdx": "2024-11-19T16:37:47.253Z",
@@ -70,8 +70,8 @@ export const generatedEditDates = {
"app/learn/fundamentals/api-routes/validation/page.mdx": "2024-12-09T13:04:02.426Z",
"app/learn/fundamentals/api-routes/errors/page.mdx": "2024-12-09T16:44:19.781Z",
"app/learn/fundamentals/admin/constraints/page.mdx": "2024-10-21T13:30:21.366Z",
"app/learn/debugging-and-testing/testing-tools/modules-tests/module-example/page.mdx": "2024-12-09T15:52:22.185Z",
"app/learn/debugging-and-testing/testing-tools/modules-tests/page.mdx": "2024-12-09T15:52:57.091Z",
"app/learn/debugging-and-testing/testing-tools/modules-tests/module-example/page.mdx": "2025-01-31T13:19:02.586Z",
"app/learn/debugging-and-testing/testing-tools/modules-tests/page.mdx": "2025-01-31T13:19:02.587Z",
"app/learn/fundamentals/module-links/custom-columns/page.mdx": "2025-01-06T11:19:13.178Z",
"app/learn/fundamentals/module-links/directions/page.mdx": "2024-12-12T15:31:31.555Z",
"app/learn/fundamentals/module-links/page.mdx": "2024-12-09T14:39:26.668Z",
@@ -110,10 +110,9 @@ export const generatedEditDates = {
"app/learn/fundamentals/data-models/check-constraints/page.mdx": "2024-12-06T14:34:50.384Z",
"app/learn/fundamentals/module-links/link/page.mdx": "2025-01-06T09:27:25.604Z",
"app/learn/conventions/ts-aliases/page.mdx": "2025-01-23T15:01:15.403Z",
"app/learn/fundamentals/workflows/store-executions/page.mdx": "2025-01-24T12:09:24.087Z",
"app/learn/fundamentals/workflows/store-executions/page.mdx": "2025-01-27T08:45:19.028Z",
"app/learn/fundamentals/plugins/create/page.mdx": "2025-01-28T07:08:05.418Z",
"app/learn/fundamentals/plugins/page.mdx": "2025-01-22T10:14:10.433Z",
"app/learn/customization/reuse-customizations/page.mdx": "2025-01-22T10:01:57.665Z",
"app/learn/fundamentals/workflows/store-executions/page.mdx": "2025-01-27T08:45:19.028Z",
"app/learn/update/page.mdx": "2025-01-27T08:45:19.030Z"
}
+36 -18
View File
@@ -870,8 +870,26 @@ export const generatedSidebar = [
"initialOpen": false
},
{
"loaded": true,
"isPathHref": true,
"type": "category",
"title": "5. Debugging & Testing",
"title": "5. Conventions",
"children": [
{
"loaded": true,
"isPathHref": true,
"type": "link",
"title": "Type Aliases",
"path": "/learn/conventions/ts-aliases",
"children": [],
"chapterTitle": "5.1. Type Aliases"
}
],
"chapterTitle": "5. Conventions"
},
{
"type": "category",
"title": "6. Debugging & Testing",
"children": [
{
"loaded": true,
@@ -879,7 +897,7 @@ export const generatedSidebar = [
"type": "link",
"path": "/learn/debugging-and-testing",
"title": "Debugging and Testing",
"chapterTitle": "5. Debugging & Testing",
"chapterTitle": "6. Debugging & Testing",
"children": [
{
"loaded": true,
@@ -888,7 +906,7 @@ export const generatedSidebar = [
"path": "/learn/debugging-and-testing/testing-tools",
"title": "Testing Tools",
"children": [],
"chapterTitle": "5.1. Testing Tools"
"chapterTitle": "6.1. Testing Tools"
},
{
"loaded": true,
@@ -904,7 +922,7 @@ export const generatedSidebar = [
"path": "/learn/debugging-and-testing/testing-tools/integration-tests/api-routes",
"title": "Example: API Routes Tests",
"children": [],
"chapterTitle": "5.2.1. Example: API Routes Tests"
"chapterTitle": "6.2.1. Example: API Routes Tests"
},
{
"loaded": true,
@@ -913,10 +931,10 @@ export const generatedSidebar = [
"path": "/learn/debugging-and-testing/testing-tools/integration-tests/workflows",
"title": "Example: Workflows Tests",
"children": [],
"chapterTitle": "5.2.2. Example: Workflows Tests"
"chapterTitle": "6.2.2. Example: Workflows Tests"
}
],
"chapterTitle": "5.2. Integration Tests"
"chapterTitle": "6.2. Integration Tests"
},
{
"loaded": true,
@@ -932,10 +950,10 @@ export const generatedSidebar = [
"path": "/learn/debugging-and-testing/testing-tools/modules-tests/module-example",
"title": "Example",
"children": [],
"chapterTitle": "5.3.1. Example"
"chapterTitle": "6.3.1. Example"
}
],
"chapterTitle": "5.3. Modules Tests"
"chapterTitle": "6.3. Modules Tests"
},
{
"loaded": true,
@@ -944,7 +962,7 @@ export const generatedSidebar = [
"path": "/learn/debugging-and-testing/instrumentation",
"title": "Instrumentation",
"children": [],
"chapterTitle": "5.4. Instrumentation"
"chapterTitle": "6.4. Instrumentation"
},
{
"loaded": true,
@@ -953,7 +971,7 @@ export const generatedSidebar = [
"path": "/learn/debugging-and-testing/logging",
"title": "Logging",
"children": [],
"chapterTitle": "5.5. Logging"
"chapterTitle": "6.5. Logging"
}
],
"childrenSameLevel": true
@@ -964,7 +982,7 @@ export const generatedSidebar = [
},
{
"type": "category",
"title": "6. Production",
"title": "7. Production",
"children": [
{
"loaded": true,
@@ -972,7 +990,7 @@ export const generatedSidebar = [
"type": "link",
"path": "/learn/build",
"title": "Build",
"chapterTitle": "6. Production",
"chapterTitle": "7. Production",
"children": [
{
"loaded": true,
@@ -981,7 +999,7 @@ export const generatedSidebar = [
"path": "/learn/deployment",
"title": "Deployment Overview",
"children": [],
"chapterTitle": "6.1. Deployment Overview"
"chapterTitle": "7.1. Deployment Overview"
},
{
"loaded": true,
@@ -990,7 +1008,7 @@ export const generatedSidebar = [
"path": "/learn/deployment/general",
"title": "General Deployment",
"children": [],
"chapterTitle": "6.2. General Deployment"
"chapterTitle": "7.2. General Deployment"
}
],
"childrenSameLevel": true
@@ -1001,7 +1019,7 @@ export const generatedSidebar = [
},
{
"type": "category",
"title": "7. Updates",
"title": "8. Updates",
"children": [
{
"loaded": true,
@@ -1009,7 +1027,7 @@ export const generatedSidebar = [
"type": "link",
"path": "/learn/update",
"title": "Updating Medusa",
"chapterTitle": "7. Updates",
"chapterTitle": "8. Updates",
"children": [],
"childrenSameLevel": true
}
@@ -1019,7 +1037,7 @@ export const generatedSidebar = [
},
{
"type": "category",
"title": "8. More Resources",
"title": "9. More Resources",
"children": [
{
"loaded": true,
@@ -1029,7 +1047,7 @@ export const generatedSidebar = [
"title": "More Resources",
"children": [],
"childrenSameLevel": true,
"chapterTitle": "8. More Resources"
"chapterTitle": "9. More Resources"
}
],
"loaded": true,
@@ -0,0 +1,32 @@
export const metadata = {
title: `Test Errors`,
}
# {metadata.title}
## Loaders for module Workflows failed
If you get the following error when running your tests:
```bash
Loaders for module Workflows failed: Method Map.prototype.set called on incompatible receiver #<Map>
```
This may occur if you have multiple test files and you don't configure your Jest environment correctly. To resolve this, add the following configuration to your `jest.config.js` file:
```js title="jest.config.js"
module.exports = {
// ...
setupFiles: ["./integration-tests/setup.js"],
}
```
Then, create the `integration-tests/setup.js` file with the following content:
```js title="integration-tests/setup.js"
const { MetadataStorage } = require("@mikro-orm/core")
MetadataStorage.clear()
```
Learn more about configuring test tools in [this documentation](!docs!/learn/debugging-and-testing/testing-tools)
+2 -1
View File
@@ -5901,5 +5901,6 @@ export const generatedEditDates = {
"references/types/HttpTypes/interfaces/types.HttpTypes.StoreProductTypeParams/page.mdx": "2025-01-27T11:43:54.211Z",
"references/types/HttpTypes/interfaces/types.HttpTypes.StoreProductTypeResponse/page.mdx": "2025-01-27T11:43:54.212Z",
"references/types/interfaces/types.BaseProductTypeListParams/page.mdx": "2025-01-27T11:43:54.550Z",
"references/core_flows/Order/Steps_Order/variables/core_flows.Order.Steps_Order.updateOrderChangesStepId/page.mdx": "2025-01-27T11:43:49.278Z"
"references/core_flows/Order/Steps_Order/variables/core_flows.Order.Steps_Order.updateOrderChangesStepId/page.mdx": "2025-01-27T11:43:49.278Z",
"app/troubleshooting/test-errors/page.mdx": "2025-01-31T13:08:42.639Z"
}
@@ -1235,6 +1235,10 @@ export const filesMap = [
"filePath": "/www/apps/resources/app/troubleshooting/s3/page.mdx",
"pathname": "/troubleshooting/s3"
},
{
"filePath": "/www/apps/resources/app/troubleshooting/test-errors/page.mdx",
"pathname": "/troubleshooting/test-errors"
},
{
"filePath": "/www/apps/resources/app/troubleshooting/workflow-errors/page.mdx",
"pathname": "/troubleshooting/workflow-errors"
+8
View File
@@ -17293,6 +17293,14 @@ export const generatedSidebar = [
"path": "/troubleshooting/workflow-errors",
"title": "Workflow Errors",
"children": []
},
{
"loaded": true,
"isPathHref": true,
"type": "link",
"path": "/troubleshooting/test-errors",
"title": "Test Errors",
"children": []
}
]
},
@@ -45,6 +45,11 @@ export const troubleshootingSidebar = [
path: "/troubleshooting/workflow-errors",
title: "Workflow Errors",
},
{
type: "link",
path: "/troubleshooting/test-errors",
title: "Test Errors",
},
],
},
{