Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

describeScenario docs #9706

Merged
Merged
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions docs/docs/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -1696,6 +1696,82 @@ Only the posts scenarios will be present in the database when running the `posts

During the run of any single test, there is only ever one scenario's worth of data present in the database: users.standard *or* users.incomplete.

### describeScenario
dac09 marked this conversation as resolved.
Show resolved Hide resolved

The scenario feature described above should be the base starting point for setting up test that depend on the database. The scenario sets up the database before each scenario _test_, runs the test, and then tears down (deletes) the database scenario. This ensures that each of your tests are isolated, and that they do not affect each other.

However, there are some situations where you as the user may want additional control regarding when the database is setup and torn down.

The `describeScenario` function is utilized to run a sequence of multiple tests within a single database setup and tear-down. T
dac09 marked this conversation as resolved.
Show resolved Hide resolved

```
describeScenario<StandardScenario>('contacts', (getScenario) => {
it('xxx', () => {
//
const scenario = getScenario()
/...
})

it('xxx', () => {
//
const scenario = getScenario()
/...
})

})
```

> **CAUTION**: With describeScenario, you no long have isolation between tests. The results, or side-effects, of prior tests can affect later tests.
dac09 marked this conversation as resolved.
Show resolved Hide resolved

Rational for using `describeScenario` include:
<ul>
<li>Create multi-step tests where the next test is dependent upon the results of the previous test (Note caution above).
dac09 marked this conversation as resolved.
Show resolved Hide resolved
<li>Reduce testing run time. There is an overhead to setting up and tearing down the db on each test, and in some cases a reduced testing run time may be of significant benefit. This may be of benefit where the likelihood of side-effects is low, such as in query testing
dac09 marked this conversation as resolved.
Show resolved Hide resolved
</ul>

### describeScenario Examples
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cjreimer thanks for these docs!

Should we change one of the examples to use a named scenario?


Following is an example of the use of `describeScenario` to speed up testing of a user query service function, where the risk of side-effects is low.

```
describeScenario<StandardScenario>('user query service', (getScenario) => {

it('retrieves a single user for a validated user', async (scenario) => {
mockCurrentUser({ id: 123, name: 'Admin' })

const scenario = getScenario()
const record = await user({ id: scenario.user.dom.id })

expect(record.id).toEqual(scenario.user.dom.id)
})

it('throws an error upon an invalid user id', async (scenario) => {
mockCurrentUser({ id: 123, name: 'Admin' })

const scenario = getScenario()
const fcn = async () => await user({ id: null as unknown as number })

await expect(fcn).rejects.toThrow()
})

it('throws an error if not authenticated', async (scenario) => {
const scenario = getScenario()
const fcn = async () => await user({ id: scenario.user.dom.id })

await expect(fcn).rejects.toThrow(AuthenticationError)
})

it('throws an error if the user is not authorized to query the user', async (scenario) => {
mockCurrentUser({ id: 999, name: 'BaseLevelUser' })

const scenario = getScenario()
const fcn = async () => await user({ id: scenario.user.dom.id })

await expect(fcn).rejects.toThrow(ForbiddenError)
})
})
```

### mockCurrentUser() on the API-side

Just like when testing the web-side, we can use `mockCurrentUser()` to mock out the user that's currently logged in (or not) on the api-side.
Expand Down
Loading