The describe function is for grouping
related specs, typically each test file has one at the top level.
The string parameter is for naming the collection of specs, and will be
concatenated with specs to make a spec's full name. This aids in finding
specs in a large suite. If you name them well, your specs read as full
sentences in traditional BDD
style.
Specs
Specs are defined by calling the global Jasmine function
it, which, like describe takes a string and a
function. The string is the title of the spec and the function is the spec, or
test. A spec contains one or more expectations that test the state of the code.
An expectation in Jasmine is an assertion that is either true or false. A spec
with all true expectations is a passing spec. A spec with one or more false
expectations is a failing spec.
Since describe and it blocks are functions, they can contain any
executable code necessary to implement the test. JavaScript scoping rules
apply, so variables declared in a describe are available to any it block
inside the suite.
Expectations are built with the function expect which takes a value, called
the actual. It is chained with a Matcher function, which takes the expected
value.
Each matcher implements a boolean comparison between the actual value and
the expected value. It is responsible for reporting to Jasmine if the
expectation is true or false. Jasmine will then pass or fail the spec.
Jasmine has a rich set of matchers included, you can find the full list in
the API docs There is also the ability to write
custom matchers for when a project's domain
calls for specific assertions that are not included in Jasmine.
To help a test suite DRY up any duplicated setup and teardown code, Jasmine
provides the global beforeEach,
afterEach,
beforeAll, and
afterAll functions.
beforeAll and afterAll can be used to speed up test suites with
expensive setup and teardown.
However, be careful using beforeAll and afterAll! Since they are not
reset between specs, it is easy to accidentally leak state between your
specs so that they erroneously pass or fail.
Another way to share variables between a beforeEach, it, and
afterEach is through the this keyword. Each spec's
beforeEach/it/afterEach has the this as the same empty object that
is set back to empty for the next spec's beforeEach/it/afterEach.
Note: If you want to use the this keyword to share variables, you must
use the function keyword and not arrow functions.
Calls to describe can be nested, with specs defined at any level. This
allows a suite to be composed as a tree of functions. Before a spec is
executed, Jasmine walks down the tree executing each beforeEach function
in order. After the spec is executed, Jasmine walks through the
afterEach functions similarly.
Suites can be disabled with the xdescribe function. These suites and any
specs inside them are skipped when run and thus their results will show as
pending.
Suites can also be focused with the fdescribe function. That means only
fdescribe suits will run.
And if you call the function pending anywhere in the spec body,
no matter the expectations, the spec will be marked pending. A string
passed to pending will be treated as a reason and displayed when the
suite finishes.
Jasmine also has support for running specs that require testing
asynchronous operations. The functions that you pass to beforeAll,
afterAll, beforeEach, afterEach, and it can be declared async.
Jasmine also supports asynchronous functions that explicitly return
promises or that take a callback. See the
Asynchronous Work tutorial for more information.
This spec will not start until the promise returned from the call to
beforeEach above is settled. And this spec will not complete until
the promise that it returns is settled.
By default jasmine will wait for 5 seconds for an asynchronous spec to
finish before causing a timeout failure. If the timeout expires before
done is called, the current spec will be marked as failed and suite
execution will continue as if done was called.
If specific specs should fail faster or need more time this can be
adjusted by passing a timeout value to it, etc.
If the entire suite should have a different timeout,
jasmine.DEFAULT_TIMEOUT_INTERVAL can be set globally, outside of any
given describe.
Jasmine has test double functions called spies. A spy
can stub any function and tracks calls to it and all arguments. A spy only
exists in the describe or it block in which it is defined, and will be
removed after each spec. There are special matchers for interacting with spies.
When there is not a function to spy on, jasmine.createSpy can create a
"bare" spy. This spy acts as any other spy - tracking calls, arguments, etc.
But there is no implementation behind it.
In order to create a mock with multiple spies, use
jasmine.createSpyObj and pass an array
of strings. It returns an object that has a property for each string that is a
spy.
[jasmine.arrayContaining](/api/edge/global.html#.arrayContaining is for
those times when an expectation only cares about some of the values in an
array.
When you need to check that something meets a certain criteria, without
being strictly equal, you can also specify a custom asymmetric equality
tester simply by providing an object that has an asymmetricMatch function.