question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Clone arguments before passing into the original function?

See original GitHub issue
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?

Issue Analytics

  • State:open
  • Created 8 years ago
  • Comments:10 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
keithamuscommented, Jun 27, 2018

It’s been a while on this one, but I agree with your points. Personally I think we should wait a while for this one, but eventually do some breaking changes - so a course of action is like this:

  1. called.with should work by reference using strict equality - currently this is not true, this would be a breaking change.
  2. deep.called.with should modify this to use deep.equal which is what today’s behavior is.
  3. For other edge caes, chai 5 will introduce matchers, which will solve this. If we add matcher support to chai-spies, then in you’d be able to do stuff like: expect(spy).to.be.called.with(expect.a('promise')).

I think this gives us full flexibility without compromising on quality. I’m happy to make breaking changes if it means good progress.

1reaction
b123400commented, Apr 4, 2015

@keithamus thanks for the quick reply.

It will involve comparing look-alike objects in solution 2, and that is a problem as well.

I am not expert in writing test, so please correct me if there is any mistake. Your first code example requires the arg1 object to be shared between the function and the testing context, which is not the case for me. Consider this example:

function runFast(speed) {
  run({ speed: speed });
}
function run(options){
  if (!('direction' in options.direction)) {
    options.direction = "left";
  }
}
run = chai.spy(run)
runFast(10);
run.should.be.called.with({ speed: 10 }) // fail
run.should.be.called.with({ speed: 10, direction: "left" }) // pass

The actual argument passed to run in is created inside the runFast and I cannot access it from the testing context.

Maybe we can conclude this programming style is bad for testing, and I should not modify arguments directly?

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to pass parameters to the function called by clone()?
One of the arguments to clone() is a void* arg . This lets you pass a void pointer to your function. In order...
Read more >
clone(2) - Linux manual page - man7.org
The arg argument is passed as the argument of the function fn. When the fn(arg) function returns, the child process terminates. The integer...
Read more >
Pass By Reference vs. Pass By Value
Pass By Value · The Twice function takes two integer parameters, and multiplies each by 2. · Note that the original variables passed...
Read more >
Pass by value vs. pass by reference - Educative.io
Pass by value means that a copy of the actual parameter's value is made in memory, i.e. the caller and callee have two...
Read more >
Function.prototype.apply() - JavaScript - MDN Web Docs
Because push() accepts a variable number of arguments, you can also push multiple elements at once. But if you pass an array to...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found