Cerebral provides testing utilities to help you test your application logic. There are two main approaches to testing in Cerebral:
Creates a snapshot test environment for your application. Pass your main module:
import { Snapshot } from 'cerebral/test'
import main from './main'
const snapshot = Snapshot(main)
Runs a sequence with an optional payload, returning a promise:
Snapshot(main)
.run('app.sequences.submitForm', { username: 'test' })
.then((snapshot) => {
expect(snapshot.get()).toMatchSnapshot()
})
Modifies state before running the sequence:
Snapshot(main)
.mutate('set', 'users.isLoading', true)
.run('app.sequences.loadUsers')
Available mutations: set
, toggle
, push
, concat
, pop
, shift
, unshift
, splice
, merge
, unset
Mocks provider methods that will be called during sequence execution:
// Mock with return value
Snapshot(main).mock('http.get', { users: [] }).run('app.sequences.loadUsers')
// Mock with function
Snapshot(main)
.mock('http.get', (context, url) => {
expect(url).toBe('/api/users')
return { users: [{ id: 1, name: 'Test' }] }
})
.run('app.sequences.loadUsers')
Mock asynchronous provider methods that return promises:
// Mock resolved promise
Snapshot(main)
.mockResolvedPromise('http.get', { users: [] })
.run('app.sequences.loadUsers')
// Mock rejected promise
Snapshot(main)
.mockRejectedPromise('http.get', { error: 'Network error' })
.run('app.sequences.loadUsers')
Test computed values:
import { runCompute } from 'cerebral/test'
import { multiply } from './computed'
it('should multiply values', () => {
const result = runCompute(multiply, {
state: { value: 5 },
props: { multiplier: 2 }
})
expect(result).toBe(10)
})
Test individual actions:
import { runAction } from 'cerebral/test'
import { increment } from './actions'
it('should increment counter', async () => {
const { state } = await runAction(increment, {
state: { count: 1 }
})
expect(state.count).toBe(2)
})
The promise resolves with an object containing:
state
: Updated stateprops
: Props passed to the actionoutput
: Action’s outputTest sequences:
import { runSequence } from 'cerebral/test'
import { submitForm } from './sequences'
it('should validate form', async () => {
const { state } = await runSequence(submitForm, {
state: { form: { username: '' } },
props: { submitted: true }
})
expect(state.form.isValid).toBe(false)
})
Create a test environment for running multiple sequences with the same controller:
import { CerebralTest } from 'cerebral/test'
import app from './app'
it('should manage user sessions', async () => {
const test = CerebralTest(app)
// Set initial state
test.setState('user.isLoggedIn', false)
// Run first sequence
await test.runSequence('user.login', {
username: 'test',
password: 'password'
})
// Check state between sequences
expect(test.getState('user.isLoggedIn')).toBe(true)
// Run another sequence
await test.runSequence('user.logout')
expect(test.getState('user.isLoggedIn')).toBe(false)
})
CerebralTest accepts an options object as second parameter:
const test = CerebralTest(app, {
throwToConsole: true, // Log errors to console
recordActions: 'byName' // Record actions by name instead of index
})
With recordActions: 'byName'
, action results are accessible by action name:
const { validateForm } = await test.runSequence('form.submit')
expect(validateForm.output.isValid).toBe(true)
Test components with Cerebral containers:
import { mount } from 'enzyme'
import App from 'cerebral'
import { Container } from '@cerebral/react'
import UserComponent from './UserComponent'
it('should render user data', () => {
const app = App({
state: {
user: { name: 'Test' }
}
})
const wrapper = mount(
<Container app={app}>
<UserComponent />
</Container>
)
expect(wrapper.find('.user-name').text()).toBe('Test')
})