Skip to main content

5. Specs

Introduction to the Specs concept

While in use cases we have the actions that the user can use from the domain. Specs are the definition of scenarios that test the expected behavior of a use case.

Previously with the execution of herbs update command, the initial code of our use cases was generated and for each of them a spec file was also generated.

We can find them side by side with our use cases:

src
└── domain
└── usecases
└── list
├── createList.js
└── createList.spec.js

Refer to Specs - Getting Started to know more.

Now, let's use createList.spec.js to learn how to create scenarios that test and validate the intent of the use case createList.js , which as its name suggests, create a list.

createList.spec

So, what is happening here? follow comments in the code to understand.


/*
Assert is a nodejs package thats provides a set of assertions functions,
see more in section: docs > specs > features > assertion
*/
const assert = require('assert')

/* Importing the main functions to create spec */
const { spec, scenario, given, check, samples } = require('@herbsjs/herbs').specs

/*
Here we can see herbarium again!
just remember thats herbarium stores all metadata for our application
*/
const { herbarium } = require('@herbsjs/herbarium')

/* Importing the use case thats we will explore scenarios */
const createList = require('./createList')


/*
We start a const createListSpec, thats assigned
with spec() function.

spec(), expects an object parameter that we will reference
a use case and we will describe its test scenarios.
*/
const createListSpec = spec({

/* Setting createList as the use case for this spec */
usecase: createList,

/*
Here we a creating a string property, thats
cleary describes a scenario thats we wanna test,
'Create a new list when it is valid'.

And throught scenario() function we are setting
the scenario conditions and its assertions.
*/
'Create a new list when it is valid': scenario({

/*
given() set to a use case of this spec,
a context mockup to test this scenario,
here is being passed request params to use case,
a user object for use case authorization and a injection
property thats contains all dependecies injections that
use case needs.

given() provides data for the test context of the
'Create a new list when it is valid' scenary
*/
'Given a valid list': given({
request: {
name: 'a text',
description: 'a text'
},
user: { hasAccess: true },
injection: {
ListRepository: class ListRepository {
async insert(list) { return (list) }
}
},
}),

// when: default when for use case
/*
the follow two properties assigned with
check() function contains asserts it will be
tested
*/
'Must run without errors': check((ctx) => {
assert.ok(ctx.response.isOk)
}),

'Must return a valid list': check((ctx) => {
assert.strictEqual(ctx.response.ok.isValid(), true)
})
}),

/*
Here we can see another scenary test
*/
'Do not create a new list when it is invalid': scenario({
'Given a invalid list': given({
request: {
name: true,
description: true
},
user: { hasAccess: true },
injection: {
listRepository: new ( class ListRepository {
async insert(list) { return (list) }
})
},
}),

// when: default when for use case

'Must return an error': check((ctx) => {
assert.ok(ctx.response.isErr)
}),
}),
})

module.exports =
herbarium.specs
.add(createListSpec, 'CreateListSpec')
.metadata({ usecase: 'CreateList' })
.spec

Finally we can run our specs to test our application, just run npm test and you can see something like this: