chaijs / chai-spies Goto Github PK
View Code? Open in Web Editor NEWSpies for Chai Assertion Library.
License: MIT License
Spies for Chai Assertion Library.
License: MIT License
The following test passes:
it('should fail', function () {
var spy = chai.spy();
spy.should.have.been.called;
});
Hi, I am currently experiencing a strange issue with checking spies calls. It seems like it works only if checking calls with unique parameters, or I am using chai wrong which I would like to be pointed at.
To reproduce:
it('checks spy calls with unique params', () => {
const math = {
multiply: function (a, b) {
return a * b;
}
};
const multiplyFunction = chai.spy.on(math, 'multiply');
math.multiply(1, 2);
chai.expect(multiplyFunction).to.have.been.called.with(1, 2);
});
it('checks spy calls with repeating params', () => {
const math = {
multiply: function (a, b) {
return a * b;
}
};
const multiplyFunction = chai.spy.on(math, 'multiply');
math.multiply(1, 1);
chai.expect(multiplyFunction).to.have.been.called.with(1, 1);
});
First test always passes, while second fails, even if putting single 1 in expectation call params.
Here is the error message:
AssertionError: expected { Spy, 1 call } to have been called with [ 1, 1 ]
at assertWith (node_modules\chai-spies\lib\spy.js:280:12)
at assert (node_modules\chai\lib\chai\utils\addChainableMethod.js:84:49)
at Context.<anonymous> (....test.ts:79:59)
at tryCatcher (core\node_modules\bluebird\js\release\util.js:16:23)
at Promise._settlePromiseFromHandler (core\node_modules\bluebird\js\release\promise.js:512:31)
at Promise._settlePromise (core\node_modules\bluebird\js\release\promise.js:569:18)
at Promise._settlePromise0 (core\node_modules\bluebird\js\release\promise.js:614:10)
at Promise._settlePromises (core\node_modules\bluebird\js\release\promise.js:693:18)
at Async._drainQueue (core\node_modules\bluebird\js\release\async.js:133:16)
at Async._drainQueues (core\node_modules\bluebird\js\release\async.js:143:10)
at Immediate.Async.drainQueues (core\node_modules\bluebird\js\release\async.js:17:14)
Also multiplyFunction.__spy field does have a call with params 1, 1
"__spy": {
"calls": [
[
1,
1
]
],
"called": true
}
Used versions:
"@types/chai-spies": "0.0.0",
"chai": "^3.5.0",
"chai-as-promised": "^6.0.0",
"chai-spies": "^0.7.1",
I tried to use spy.interface
, but seem that interface
method does not exist in @types/chai-spies
.
I checked DefinitelyTyped
and there's reference to old method object
: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/chai-spies/index.d.ts#L155 It needs to be renamed to interface
In
http://chaijs.com/plugins/chai-spies
under "Tests" it's "in the BDD itnerface", but I guess you ment interface, instead of itnerface?
When I enter this code in TypeScript it does not compile:
import { expect } from 'chai';
import { spies } from 'chai-spies';
chai.use(spies);
Error: Module '"chai-spies"' has no exported member 'spies'.
You should probably have a guide for TypeScript in the README.
Thanks!
Jim
I just installed via npm install chai-spies
as documented and noticed I have installed this NPM package which is not this repository.
Strangely I can also see that they are both are the same version 0.7.1
even though the one I have installed lacks some of the functionality that the readme documents.
I think you might need to publish to NPM again!
Thanks
I don't know is there any function or not!
Please let me know is it possible?
Something like that:
spy(obj, 'funcName').and.returnValue(5);
// spy will return a fake data when called`
One big problem with spies is being able to quickly restore old behaviour, when you want the function to execute its original behaviours.
Now we have chai.spy.on(object, ...methods);
I think we could track which methods we spy on what objects. We could implement some kind of sandboxing:
sandbox = chai.spy.sandbox();
sandbox.spy.on(myArray, 'push', 'pull');
sandbox.spy.restore(myArray, 'push');
sandbox.spy.restoreAll();
The main export of chai-spies could also be a sandbox in of itself - and so:
chai.spy.on(myArray, 'push', 'pull');
chai.spy.restore(myArray, 'push');
chai.spy.restoreAll(); // restores Array.pull
Potentially we could also make a decorator/higher order function which would help inside of tests; for example:
test(chai.spy.sandbox(function (spy) {
expect(spy()).to.be.a('function');
}));
This is just a rough draft of what I have in my head - I'd very much like feedback, especially from @stalniy who has been doing some great contributions lately, including the improved chai.spy.on
interface.
function fn(options) {
options.foo = 1;
}
spy = chai.spy(fn);
spy({ bar : 1 });
spy.should.be.called.with({ bar : 1 }); // fail
This happens because the function fn
modifies the argument, and the spy compares the modified object instead of the original version.
Do you think it makes sense if we store a shallow cloned argument instead of using the argument directly?
At least three places reference the old repo: logicalparadox/chai-spies which is a dead link.
I'm happy to open a PR for 1 but I don't know where to fix 2 and 3.
"chai": "^4.1.2",
"chai-as-promised": "^7.1.1",
"chai-spies": "^0.7.1",
Hi there,
I am testing a little ORM I created myself
I am having some problems testing the result of a spy on a promise, the test always passes, no matter what I put inside with, in the example below I just put null, although query should be called with a SELECT SQL sentence
Any suggestions?
it('test SQL',
() => {
Item.database = { query: queryReturnsInsert };
const item = new Item();
item.name = 'James';
const spy = chai.spy.on(Item.database, 'query');
item.save({ in: 'go' })
.then(function() {
expect(spy).to.have.been.called.with(null);
});
});
Branch | Build failing π¨ |
---|---|
Dependency | mocha |
Current Version | 3.4.0 |
Type | devDependency |
This version is covered by your current version range and after updating it in your project the build failed.
As mocha is βonlyβ a devDependency of this project it might not break production or downstream projects, but βonlyβ your build or test tools β preventing new deploys or publishes.
I recommend you give this issue a high priority. Iβm sure you can resolve this πͺ
Fixed a publishing mishap with git's autocrlf settings.
There is a collection of frequently asked questions and of course you may always ask my humans.
Your Greenkeeper Bot π΄
chai version: 4.0.0
chai-spies version: 0.7.1
Node.js version: 7.10.0
expect(spy).to.be.called.with(...)
fails with:
Error: Invalid Chai property: _his. Did you mean "is"?
at Object.proxyGetter [as get] (node_modules/chai/lib/chai/utils/proxify.js:63:17)
at Proxy.assertWith (node_modules/chai-spies/lib/spy.js:283:29)
at Proxy.chainableMethodWrapper (node_modules/chai/lib/chai/utils/addChainableMethod.js:113:49)
Besides that, if this is a breaking change in the public API for plugin authors, it should probably have been mentioned in the release notes for [email protected]
.
Thanks!
Thanks for merging in #28 π
Do you mind bumping the package.json
version and publishing to npm? I work on an application that pulls this in via npm and it would be great to have that new method for our unit tests. Thanks!
Hi there,
I have a small issue with chai spies.
import * as spies from 'chai-spies';
const assert = chai.assert;
const expect = chai.expect;
beforeEach(() => {
chai.use(spies);
spy = chai.spy.on(component.change, 'emit');
});
it('should have been called with string foo', () => {
expect(spy).to.have.been.called.with('foo');
});
When invoking the above code I receive an error:
Error: Invalid Chai property: _his. Did you mean "is"?
at Object.proxyGetter [as get] (node_modules/chai/chai.js:9105:17)
I don't have any problems with running other functions so far like to.have.been.called.once/twice etc.
Is it a known issue?
I use chai version 4.0.2 and chai-spies version 0.7.1
Example on how it could work:
var add = function (a, b) {
return a + b;
}
spy = chai.spy(add);
add(40, 2);
spy.should.have.been.called.with(40, 2)
Hello,
mind bumping up the npm package version with the latest commits? chai.spy.on
is working great
Suppose I have a setup such that
a()
.then(b)
.then(c)
Is there a way to verify that b runs before c using chai-spies?
Looking at the interface documentation it seems to be slightly incorrect if you try and create an object through the array-of-keys syntax.
Particularly, it says you can do something like chai.spy.interface(['on', 'off', 'emit']);
.
However, looking at the tests, there is no such expectation of being able to create an interface in that way. You need to pass a "base class" to create the interface from, like chai.spy.interface("Object", ['on', 'off', 'emit']);
.
Creating an interface in the way the documentation suggests creates a weird object with integer keys, which is not quite what you want.
The docs imply that the methods for ranges are called max
and min
, but the source says above
and below
(or lt
and gt
).
I wonder if this code is really needed? I found that it breaks reading names of functions parameters (like here). I use some DI container that parses function definition string and because of that, I can test my modules only when I wrap spy in pure function.
let spy = chai.spy('justSpy');
annotatedFn(() => spy());
expect(spy).to.have.been.called.once();
So I can live with that, but I just wonder if anything can be improved.
Not a big deal but http://chaijs.com/plugins/chai-spies shows the readme on the master branch which includes the new chai.spy.return feature. This feature thats on master hasn't been tagged and released yet. So if you follow the instructions npm install chai-spies. The api for chai.spy.returns is missing.
You come to the gh repo and master has spy.returns. Should this be tagged and released?
Adding the chai-spies.js file to my HTML spec runner file, makes this assertion fail:
expect(ret.__observable).to.have.property('ids').with.length(1)
It throws this error:
TypeError: Property 'length' of object function () {
var result = method.apply(this, arguments);
return result === undefined ? this : result;
} is not a function
If I comment out the line where I include chai-spies.js it passes again. I'm not using any spies yet.
How to reproduce:
$ git clone https://github.com/js-coder/observable.git
$ cd observable
$ git checkout v1.2.0
# open spec/index.html
I guess that's a bug?
The readme states up front that the primary purpose of chai-spies is to serve as an example of how to create a Chai plugin. This statement suggests that its role as a mocking library is secondary. It mentions that only the most basic of functionality is provided, and even goes so far as to recommend an alternative library if advanced functionality is desired.
Of course, just because those words were written x
years ago doesn't mean they're true now, or that it's the way things should be going forward. However, as the Chai ecosystem grows and the number of maintainers increases, I think it's valuable to reach an understanding on what the goal of chai-spies is so that we're all of the right mindset when evaluating feature requests.
My opinion is that the originally stated goal and minimalistic scope of chai-spies should be strictly maintained, and that when it comes to users requesting advanced features, we should point them at sinon and chai-sinon. I think we do more good for the community overall by throwing our support behind these existing libraries rather than duplicating their efforts, and that chai-spies fulfills its own niche quite nicely as being super minimalistic.
With that said, I'll fall in line behind the popular opinion on this issue. Achieving clarity in the goal of chai-spies is more important to me than my opinion. But in that case I'd like to learn more about what the strengths of chai-spies are in comparison to sinon and sinon-chai, other than it being lightweight, so that we can work to maximize those strengths going forward.
I've noticed that if you do something like
const object = Object.create(null);
object.method = function() {};
chai.spy.on(object, 'method');
it will throw an error because it uses
object.hasOwnProperty(methodName);
This can be fixed easily by changing it to
Object.hasOwnProperty.call(object, methodName);
I will file a PR for this.
I've encountered the issue in the context of migrating to Vue 3 and using @vue/test-utils. Apparently if you mount a component like
import { mount } from '@vue/test-utils';
let { vm } = mount(Component);
then vm
is an object with null
as its prototype. If you then want to spy on some of its methods with chai.spy.on
, it throws the error above.
Branch | Build failing π¨ |
---|---|
Dependency | mocha |
Current Version | 3.5.3 |
Type | devDependency |
This version is covered by your current version range and after updating it in your project the build failed.
As mocha is βonlyβ a devDependency of this project it might not break production or downstream projects, but βonlyβ your build or test tools β preventing new deploys or publishes.
I recommend you give this issue a high priority. Iβm sure you can resolve this πͺ
You might want to read this before filing a new bug! π
For more info, please read this article.
node
from exiting will do so when run in Mocha. Supply the --exit
flag to revert to pre-v4.0.0 behavior (@ScottFreeCode, @boneskull)stdout:
prefix from browser reporter logs (@skeggse)--forbid-pending
or --forbid-only
is specified (@ScottFreeCode)--compilers
command-line option is now soft-deprecated and will emit a warning on STDERR
. Read this for more info and workarounds (@ScottFreeCode, @boneskull)The new version differs by 48 commits.
d69bf14
Release v4.0.0
171b9f9
pfix "prepublishOnly" potential portability problem
60e39d9
Update link to wiki (GitHub at the leading --
)
804f9d5
Update link because GitHub ate the leading --
3326c23
update CHANGELOG for v4.0.0 [ci skip]
6dd9252
add link to wiki on --compilers deprecation
96318e1
Deprecate --compilers
92beda9
drop bower support
58a4c6a
remove unused .npmignore
7af6611
kill Date#toISOString shim
43501a2
reduce noise about slow tests; make a few tests faster, etc.
fa228e9
update --exit / --no-exit integration test for new default behavior
3fdd3ff
Switch default from forced exit to no-exit
c5d69e0
add integration tests for --exit/--no-exit
3a7f8dc
enhance runMochaJSON() helper by returning the subprocess instance
There are 48 commits in total.
See the full diff
There is a collection of frequently asked questions and of course you may always ask my humans.
Your Greenkeeper Bot π΄
Please consider packaging and publishing the plugin as bower package.
Branch | Build failing π¨ |
---|---|
Dependency | rollup-plugin-commonjs |
Current Version | 8.2.1 |
Type | devDependency |
This version is covered by your current version range and after updating it in your project the build failed.
rollup-plugin-commonjs is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.
The new version differs by 15 commits.
3724521
8.2.3
33ce531
8.2.2
8d53cca
Merge pull request #233 from mbostock/fix-require-collision
7c14734
Remove apparently-unneeded file.
386a1e7
Add test for require collision.
93cedc2
Fix #232 - require collision.
419a912
Update dependencies
d3cd998
Merge pull request #241 from rollup/update-test-config
8efa096
Silence a few test warnings
77c4838
Merge pull request #230 from caleb531/duplicate-export-fix
6a3046e
Merge pull request #229 from DenisCarriere/patch-1
83315ad
Merge pull request #226 from marijnh/master
4dae460
Make unwrapExports only pick out default when it exists
e49819a
Fix rollup/rollup#1637 (with tests)
a453bb4
Update README.md
See the full diff
There is a collection of frequently asked questions. If those donβt help, you can always ask the humans behind Greenkeeper.
Your Greenkeeper Bot π΄
5.2.0
to 6.0.0
.π¨ View failing branch.
This version is covered by your current version range and after updating it in your project the build failed.
mocha is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.
--grep
and --fgrep
are now mutually exclusive; attempting to use both will cause Mocha to fail instead of simply ignoring --grep
--compilers
is no longer supported; attempting to use will cause Mocha to fail with a link to more information-d
is no longer an alias for --debug
; -d
is currently ignored--watch-extensions
no longer implies js
; it must be explicitly added (@TheDancingCode)tap
reporter emits error messages (@chrmod)before
hook, subsequent before
hooks and tests in nested suites are now skipped (@bannmoore)lib/template.html
has moved to lib/browser/template.html
(@boneskull)mocha.opts
at a user-specified path (@plroebuck)Base
-extending reporter without a Runner
parameter will throw an exception (@craigtaub)code
property (and some will have additional metadata). Some Error
messages have changed. Please use the code
property to check Error
types instead of the message
property; these descriptions will be localized in the future. (@craigtaub)These are soft-deprecated, and will emit a warning upon use. Support will be removed in (likely) the next major version of Mocha:
-gc
users should use --gc-global
insteadbin/options
should now use the loadMochaOpts
or loadOptions
(preferred) functions exported by the lib/cli/options
moduleRegarding the Mocha
class constructor (from lib/mocha
):
color: false
instead of useColors: false
timeout: false
instead of enableTimeouts: false
All of the above deprecations were introduced by #3556.
mocha.opts
is now considered "legacy"; please prefer RC file or package.json
over mocha.opts
.
require
cache (@plroebuck)Enhancements introduced in #3556:
Mocha now supports "RC" files in JS, JSON, YAML, or package.json
-based (using mocha
property) format
.mocharc.js
, .mocharc.json
, .mocharc.yaml
or .mocharc.yml
are valid "rc" file names and will be automatically loaded--config /path/to/rc/file
to specify an explicit path--package /path/to/package.json
to specify an explicit package.json
to read the mocha
prop from--no-config
or --no-package
to completely disable loading of configuration via RC file and package.json
, respectivelypackage.json
mocha.opts
Node/V8 flag support in mocha
executable:
node
flags as supported by the running version of node
(also thanks to @demurgos)--v8-
to the flag namepackage.json
properties, or mocha.opts
--inspect
) now imply --no-timeouts
--debug
will automatically invoke --inspect
if supported by running version of node
Support negation of any Mocha-specific command-line flag by prepending --no-
to the flag name
Interfaces now have descriptions when listed using --interfaces
flag
Mocha
constructor supports all options
--extension
is now an alias for --watch-extensions
and affects non-watch-mode test runs as well. For example, to run only test/*.coffee
(not test/*.js
), you can do mocha --require coffee-script/register --extensions coffee
.
#3552: tap
reporter is now TAP13-capable (@plroebuck & @mollstam)
#3535: Mocha's version can now be queried programmatically via public property Mocha.prototype.version
(@plroebuck)
#2529: Runner
now emits a retry
event when tests are retried (reporters can listen for this) (@catdad)
#2962, #3111: In-browser notification support; warn about missing prereqs when --growl
supplied (@plroebuck)
Suite#_onlyTests
and Suite#_onlySuites
(@vkarpov15)lookupFiles
and files
(@plroebuck)--delay
(and other boolean options) not working in all cases (@boneskull)--reporter-option
/--reporter-options
did not support comma-separated key/value pairs (@boneskull)mocharc.json
in published package (@boneskull)--no-timeouts
and --timeout 0
now does what you'd expect (@boneskull)--no-exit
option (@boneskull)SIGINT
(@boneskull)--forbid-only
and --forbid-pending
now "fail fast" when encountered on a suite (@outsideris)start
and end
events now emitted properly from Runner
instance when using Mocha programmatically (@outsideris)stdout:
prefix in browser console (@Bamieh)utils.isPromise()
(@fabiosantoscode)--bail
would not execute "after" nor "after each" hooks (@juergba)TERM=dumb
(@plroebuck).github/CONTRIBUTING.md
(@markowsiak)slow
option (@finfin)--watch
docs (@benglass)ms
userland module instead of hand-rolled solution (@gizemkeser)The new version differs by 209 commits ahead by 209, behind by 39.
42303e2
Release v6.0.0
a553ca7
punctuation updates for changelog v6.0.0
c710792
grammar updates for changelog v6.0.0
9f9293a
update changelog for v6.0.0
a540eb0
remove "projects" section from MAINTAINERS.md [ci skip]
52b5c42
Uppercased JSON reporter name in describe
title (#3739)
82307fb
Fix .globals
to remove falsy values (#3737)
56dc28e
Remove unnecessary post-processing code having no effect; closes #3708 (#3733)
16b4281
Documentation updates (#3728)
5d9d3eb
Update nyc
118c9ae
Refactor out usages of Suite#_onlyTests and Suite#_onlyTests (#3689) (#3707)
0dacd1f
Add ability to unload files from require
cache (redux) (#3726)
66a52f2
update release steps [ci skip]
45ae014
Refactor lookupFiles
and files
(#3722)
94c9320
fix --reporter-option to allow comma-separated options; closes #3706
There are 209 commits in total.
See the full diff
There is a collection of frequently asked questions. If those donβt help, you can always ask the humans behind Greenkeeper.
Your Greenkeeper Bot π΄
I'm currently writing tests for message passing with the cluster module. In some cases it would be useful to check that a number of certain type of message were received.
What this feature request amounts to is some sort of .exactlyWith
.
Additionally, consider something like .exactlyWhen
which could only bump the count if the args match a filter.
spy.should.have.been.called.exactly(3).when(function (a, b) { return a > b });
I mentioned in a comment on #39 that I'm migrating a large project from jasmine 1.x to mocha. I really want to avoid using sinon-chai and would much rather roll with pure chai goodness. Jasmine however, has a magical little call that's prolific in our test codebase:
spyOn(object, 'method').andReturn(someValue);
Best I can tell, that's altogether missing from this lib. If there's a method I've missed, or there's a way to achieve the same, please do share it. I dare say it's not spelled out very clearly anywhere. But then I might be a big dummy.
Anyhow, this would be a grand feature to have.
Hello,
is there a method to reset a spy object for reuse?
var boom = chai.spy(originalFn);
originalFn();
expect(boom).to.have.been.called.once; // passes
boom.reset();
expect(boom).to.have.been.called.once; //fails
Was helpful in another test framework and thought it would be great here. I can open up a pull request too if it's a matter of resetting some internal vars for the callCount
Asserting that a function has been called with a given parameter fails if that function was called with that parameter with an arity greater than one.
For example, the following assertions fail if the function sum
is called with sum(1, 1)
.
expect(sum).to.have.been.called.with(1)
(1)
expect(sum).to.have.been.called.with(1, 1)
(2)
The reason is that the function assertWith
counts all the occurrences of the parameters for each argument and then expects it to be equal to the length of the arguments.
Assertion (1) will fail because 1
appears twice in the arguments list, but the length of the with
arguments is 1.
Assertion (2) will also fail because 1
appears twice in the arguments list, so for every with
argument it is counted twice, so it's been found "4" times.
The following code causes a TypeError: Cannot use 'in' operator to search for 'Date' in global
:
describe("now", () => {
it("returns a properly formatted date", () => {
chai.spy.on("global", "Date", () => {
return new Date("2018-09-07T10:29:01.000Z");
});
const result = now();
expect(result).to.equal("9/7/2018 7:29:1");
});
});
Any ideas?
The current restore
method has issues when dealing with multiple spies.
Current code with my comments, showing the flaws:
Sandbox.prototype.restore = function (object, methods) {
// actually `hasFilter` is more a `exitAfterOneSpyIsRestored`
var hasFilter = Boolean(object && methods);
var sandbox = this;
if (methods && !Array.isArray(methods)) {
methods = [methods]
}
// remember that sandbox === this
Object.keys(this[STATE_KEY]).some(function (spyId) {
var spy = sandbox[STATE_KEY][spyId];
var tracked = spy.__spy.tracked;
// `isXxxSpied` is more `shouldXxxBeRestored`, based on the request made through input
var isObjectSpied = !object || object === tracked.object;
var isMethodSpied = !methods || methods.indexOf(tracked.methodName) !== -1;
// issue: we're deleting a reference to the currently parsed spy (sandbox === this)
// however, there's no reason we should de-reference it since we don't know whether
// we should restore this one yet
delete sandbox[STATE_KEY][spyId];
// issue: we're saying "don't restore this spy if !(shouldObjectBeRestored || shouldMethodBeRestored)"
// we want to say "don't restore if neither the object nor the method should be restored"
// here we allow restore(object, 'method') to restore all spied methods on object
if (!isObjectSpied && !isMethodSpied) {
return false;
}
sandbox.restoreTrackedObject(spy);
// issue: methods can be an array of several methods, this makes the process stop
// as soon as the first method is restored
// this issue combined with the previous condition makes you restore ANY method
// on the object, not ensuring that's the correct one nor the only one requested
if (hasFilter) {
return true;
}
});
return this;
};
Here is a fixed version:
Sandbox.prototype.restore = function (object, methods) {
var exitAfter = 0, restored = 0;
var sandbox = this;
if (methods) {
if (!Array.isArray(methods)) {
methods = [methods]
}
// set the end-of-process shortcut properly, only if `methods` was populated and is now an array
exitAfter = methods.length;
}
Object.keys(this[STATE_KEY]).some(function (spyId) {
var spy = sandbox[STATE_KEY][spyId];
var tracked = spy.__spy.tracked;
// these 2 bools mean "should we process this spy", not "do we spy this object[ and method]"
// since, anyway, this[STATE_KEY] *is* the list of spies we own
var shouldRestoreThisObject = !object || object === tracked.object;
var shouldRestoreThisMethod = !methods || methods.indexOf(tracked.methodName) !== -1;
// equivalent to !(should...Object && should...Method)
// this wouldn't work if we could provide a method without providing an object
if (!shouldRestoreThisObject || !shouldRestoreThisMethod) {
// we were not asked to restore this spy: next!
return false;
}
// remove from the list of spies now that we know we'll restore this one
delete sandbox[STATE_KEY][spyId];
// do the restoring
sandbox.restoreTrackedObject(spy);
if (++restored === exitAfter) {
// we were asked to restore that many spies, we did, get out now
// we never enter this block if exitAfter stays at zero (i.e. no shortcut)
return true;
}
});
return this;
};
In some cases is needed to check that the same spy has been called multiple times with different parameters (eg: while testing a curried function)
This is a possible desired feature, suggested by @keithamus:
const spy = chai.spy();
spy('a');
spy('b');
spy('c');
expect(spy).to.first.be.called.with('a');
expect(spy).to.second.be.called.with('b');
expect(spy).to.third.be.called.with('c');
It could be hard to match/generate first
, second
, third
, nth
property in the assertion chain.
Another possible assertion structure is:
const spy = chai.spy();
spy('a');
spy('b');
spy('c');
expect(spy).to.have.been.called.with.ordered('a', 'b', 'c');
Atm one as to register the spies before beeing able to use it with the chai-object chai.spy
However, I like to import only what I need:
import {expect, use} from 'chai'
import spies from 'chai-spies'
use(spies)
As you can see I cannot grab the spy function because its not available at import time.
Thats why it would be cool to have a named export on chai-spies
which returns a wrapper to the chai.spy
. That way you can do:
import {expect, use} from 'chai'
import spies, {spy} from 'chai-spies'
use(spies)
What do you think?
A previous issue #27 introduced the reset method to this library which we use extensively. It was removed in 1.0 for no clear reason. I'd like to see it put back
chai.spy.callsBackWith
simply creates a spy that expects the last argument it was called with to be a callback function and calls it with the arguments provided in its constructor.
var methodA = chai.spy.callsBackWith(new Error('foo'));
methodA(cb);
// cb would be called with one argument: new Error('foo')
var methodB = chai.spy.callsBackWith(null, {id:12});
methodB(cb);
// cb would be called with two arguments: null and {id:12}
Hey guys,
How can I use to.have.been.called.with
? I have a function, which in case of receiving an array as data param, calls itself array.length times.
Like this:
var spy = chai.spy.on(dataHandler.pubsub, 'emit');
var data = [
{id: 123123, a: true, f: 'match'},
{id: 232323, a: true, f: 'event'},
{id: 511515, a: false, f: 'lineups'}
];
var promise = dataHandler.save('match', data); // dataHandler.pubsub.emit is called within
expect(spy).to.have.been.called.exactly(3); // ok
expect(spy).to.have.been.called.with(->> HOW??? <<-);
Thanks.
Is there a way to check that nested method have been called?
class A {
constructor(b) {
this.b = b;
}
functionA() {
this.b.aFunctionInOtherClass();
}
}
I can check that functionA has been called as follows:
const chai = chai.spy.on(a, 'functionA')
expect(spy).to.have.been.called();
But how can I check the aFunctionInOtherClass also have been called?
I have asynchronous mocha test with spied function being called many times with different parameters.
I'd like to verify the input on first and second calls, then complete the test case. How do you do that with chai-spies?
The minimal working example at here
I am using Mocha and Chai with Chai Spies.
I want to test if a method (called ack|nack in the MWE) got called in a promise, so I basically need to use chai-as-promised with chai-spies, but
expect(notificationListener.nack).to.be.eventually.called();
is not allowed.
How can I avoid using setTimeout(()=>expect(notificationListener.nack).to.be.called(), 1000), to mitigate this issue?
Additionally, I cannot return the Promise in my actual code, since it would mess up other stuff.
I have a suite of tests using chai spies. Basically, every test case attaches a new spy and records the number of times that spy gets called, and with which arguments.
All is fine, until I switch from 0.7.1
to the master
branch where I get the following error:
Error: "foo" is already a spy
Here is a simple script that replicates the issue:
const chai = require('chai');
const spies = require('chai-spies');
const { EventEmitter } = require('events');
chai.use(spies);
const emitter = new EventEmitter();
function foo() {
const spy = chai.spy.on(emitter, 'emit');
};
function bar() {
const spy = chai.spy.on(emitter, 'emit');
}
foo(); // OK
bar(); // Error: "emit" is already a spy
The above script works fine on version 0.7.1
, but throws the error on the master
branch. This looks to me like a regression.
I have used Node EventEmitter here, but you can reproduce with any other function.
Regards
chai version: 4.0.1
chai-spies version: 0.7.1
Node.js version: 6.10.3
I upgraded chai and chair-spies and ran into the following error
expect(spy).to.have.been.called.once()
fails with:
Unhandled rejection TypeError: expect(...).to.have.been.called.once is not a function
Would appreciate any help or direction on how to figure this issue out.
Thanks
Hey Jake
Could you republish [email protected] the tag was created before we added component.json and this cause new version of component to fail to download the package
to be specific component tries to download the file from this url which does not exist
https://api.bitbucket.org/1.0/repositories/chaijs/chai-spies/raw/v0.5.1/component.json
Please include a report to get the called.with assertions which shows which arguments were actually called.
This is a suggestion I came up with:
in spy.js, for any called.with assertion, add the argument spy.calls.find(args => !_.eql(args, expArgs))
not sure if its possible to react to negations - that would be the only problem
this.assert(
passed > 0
, 'expected ' + this._obj + ' to have been called with #{exp}'
, 'expected ' + this._obj + ' to have not been called with #{exp} but got ' + passed + ' times'
, expArgs
, spy.calls.find(args => !_.eql(args, expArgs))
);
thanks and best regards
Come on folks, this one is a baddie. Because of the slow release cycle of this module, folks are depending on installing from master
(which is bad enough in of itself). Please get this file up to date with the rest of the repo on master.
Hey guys,
I have an issue during testing bound functions.
// instanceName.onDisconnect = ... this.property = true ...
// ...
let spy = chai.spy.on(instanceName, 'onDisconnect');
instanceName.connection.on('end' , instanceName.onDisconnect.bind(instanceName));
instanceName.connection.end();
expect(instanceName.property).to.be.ok; // ok
expect(spy).to.have.been.called(); // fail
/* BUT IF! */
let spy = chai.spy.on(instanceName, 'onDisconnect');
instanceName.connection.on('end' , () => instanceName.onDisconnect());
instanceName.connection.end();
expect(instanceName.property).to.be.ok; // ok
expect(spy).to.have.been.called(); // ok
So as you can see from the example, if function is bound, then it fails, but if it is called directly, then it passes.
I think it is an issue.
Please advise, thanks.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.