Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/fizker/fzkes
A faking library
https://github.com/fizker/fzkes
Last synced: 4 days ago
JSON representation
A faking library
- Host: GitHub
- URL: https://github.com/fizker/fzkes
- Owner: fizker
- Created: 2013-05-13T21:47:32.000Z (over 11 years ago)
- Default Branch: master
- Last Pushed: 2017-04-02T21:33:37.000Z (over 7 years ago)
- Last Synced: 2024-08-09T04:57:40.412Z (3 months ago)
- Language: JavaScript
- Size: 65.4 KB
- Stars: 1
- Watchers: 3
- Forks: 1
- Open Issues: 6
-
Metadata Files:
- Readme: readme.md
Awesome Lists containing this project
README
fzkes
=====A faking library
I must immediately apologize for the name; it is a horrible pun combining `fzk`
(a shortening of the name of my company) and `fakes`. But it does have a nice ring to it,
and I want it to be short and unique. So there it is.How to use
----------### Creating fakes
var fzkes = require('fzkes')
// Creating a stand-alone fake, great for use as a callback
var fake = fzkes.fake()// For overriding an original function, great for restoring later
var fs = require('fs')
fzkes.fake(fs, 'readFile')// For faking all functions on an object
fzkes.fakeAll(fs)#### fakeAll
The `fzkes.fakeAll()` function can take an options-dictionary, allowing for
overriding the default action. The options are:- `callsOriginal`: The default. `fake.callsOriginal()` is evoked on all fakes.
- `none`: No action is taken on the fakes.
- `throws`: A `'Fake not overridden'` exception will be evoked on all fakes.All fakes can of course be overridden later on, the default is just what should
happen out-of-the-box.### Resetting fakes
Resetting a fake (`fake.reset()`) will set its internal state to what it was
when it was new.It is possible to reset all fakes by calling `fzkes.reset()` or `scope.reset()`.
### Restoring original functions
There are three ways to easily doing this, depending on the scope:
1. Restoring a single fake: `fake.restore()`
2. Restoring all fakes across the board: `fzkes.restore()`The last is a bit more tricky; A sub-scope can be creating by calling
`fzkes.scope()`. The scope have all methods (except `chai`) that the original
`fzkes` object have, except the `restore()` function on a scope only affects
fakes created within that scope.### Injecting data
fake.returns('abc')
fake.throws(new Error('some error'))
fake.calls(function() { console.log('was called') })// If it replaced a function on an object:
fake.callsOriginal()// Conditional injects
fake.withArgs(1,2).returns(3)
fake.withArgs(1,2).callsOriginal()Each action (`returns`, `throws`, `calls`, etc) returns the fake, to make it
easier to assign to return values and the like:fake.returns({
a: fzkes.fake('a').returns(3),
b: fzkes.fake('b').throws()
})It can also chain the withArgs() automatically:
var fake = fzkes.fake('name')
.returns(1)
.withArgs(1,2).returns(3)
.withArgs(1,3).returns(4)
.withArgs(1,4).throws(new Error('some error'))
fake(1,1) // => 1
fake(1,2) // => 3
fake(1,3) // => 4
fake(1,4) // => throws#### Advanced `withArgs`
There is a more advanced form of `withArgs` called `withComplexArgs`.
It allows for skipping arguments entirely, as well as defining regular
expressions to validate against strings.var fake = fzkes.fake('name')
.returns(1)
.withComplexArgs(null, { value: 2 }).returns(2)
.withComplexArgs({ regex: /ab?c/ }).returns(3)fake(1, 1) // => 1
fake(1, 2) // => 2
fake('a', 2) // => 2
fake('abc') // => 3
fake('ac') // => 3### Calling callbacks
There is a built-in helper for calling callbacks: `callsArg`. If the callback
throws an exception, the fake with throw it as well.It can take the following options:
- `notify`: A function to notify whenever the fake is called. It is called as
`function(error, returnValue)`, where `error` is whatever the callback
threw, and `returnValue` is what the callback returned. If `async` is
false, the fake will return whatever the `notify` function returns.This option is also perfect for [mocha][mocha] style async handlers.
- `returns`: A value to return whenever the fake is called. This takes
presedence over the return-value of `notify`, but exceptions still triumph.- `now`: A flag that determines if the action should occur for future calls or
for the first unhandled call. This will throw if the fake have no unhandled
calls.- `async`: A flag determining if the callback should be called immediately or in
the next tick (which would simulate an async call).- `arg`: The argument to call. This can be the parameter index (0-n), `'first'`
or `'last'`. It defaults to `'last'`.- `arguments`: An array of the arguments to pass to the callback.
Examples follow:
// Default is calling the last function found, node-style
fake.callsArg()// It can be controlled
fake.callsArg({ arg: 'first' })
// 0-indexed argument list
fake.callsArg({ arg: 1 })// It defaults to calling the callback immediately, but this can be changed
fake.callsArg({ async: true })// Default is no parameters to the callback, but these can be controlled
fake.callsArg({ arguments: [ 1, 2 ] })[mocha]: http://mochajs.org/
### Emulating calls after they have been called
Sometimes, it is not feasible to prepare the fake properly; in these cases,
emulating the call after the fact makes the code much better.`fzkes` supports this as an option for the `fake.calls()`, `fake.callsArg()` and
`fake.callsOriginal()` functions.The code would look as the following:
fake(1,2,3)
fake.calls(fn, { now: true })
fake.callsOriginal({ now: true })
fake.callsArg({ now: true })It works with all other options on the `fake.callsArg()` call.
It forwards the next unhandled call as it appeared on the `fake`, and throws an
exception if there are no unhandled calls:fake(1,2,3)
// Goes through
fake.callsOriginal({ now: true })try {
fake.calls(fn, { now: true })
} catch(e) {
// e.message would say that fake had no unhandled calls.
}If any of the functions was set up in advance, calls are not considered
unhandled, and any call with `{ now: true }` will throw an exception.
To begin building unhandled calls, make a `fake.calls(null)` invocation.fake.callsOriginal()
// this call is handled immediately
fake()
expect(function() {
fake.callsOriginal({ now: true })
}).to.throw()// resetting the expectations
fake.calls(null)// it now works again
fake()
fake.callsOriginal({ now: true })### Asserting
fake.wasCalled()
fake.wasCalledWith(1, 2, 3)
fake.wasCalledWithExactly(1, 2, 3)
fake.callCount == 2### Using with [chai](http://chaijs.com)
chai.use(fzkes)
fake.should.have.been.called // at least once
fake.should.have.been.called(2) // precisely 2 times
fake.should.have.been.calledWith(1,2,3)### Running in the browser
Use a tool like browserify or webpack to generate a browser-compatible version
of the tests. Then simply follow the guide above for setting it up and
interacting with it.__NOTE:__ Pre v0.15, the package built a browser-version always. This task have
now been delegated to the consumer of the library.