Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

expect(spy).to.have.been.called.with always true #82

Open
xavicolomer opened this issue Sep 12, 2017 · 6 comments
Open

expect(spy).to.have.been.called.with always true #82

xavicolomer opened this issue Sep 12, 2017 · 6 comments

Comments

@xavicolomer
Copy link

xavicolomer commented Sep 12, 2017

"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);
        });
    });
@vieiralucas
Copy link
Member

I think you need to return the Promise so the test runner can wait on it.
It looks like the assertion never runs.
Try:

it('test SQL', () => {
  Item.database = { query: queryReturnsInsert };

  const item = new Item();
  item.name = 'James';

  const spy = chai.spy.on(Item.database, 'query');

  return item.save({ in: 'go' })
    .then(function() {
      expect(spy).to.have.been.called.with(null);
    });
});

@xavicolomer
Copy link
Author

xavicolomer commented Sep 12, 2017

@vieiralucas You are right, but now I get this:

AssertionError: expected { Spy, 1 call } to have been called with [ Array(3) ]

After changing it the last code to what should return

it('test SQL',
    () => {
      Item.database = { query: queryReturnsInsert };

      const item = new Item();
      item.name = 'James';

      const spy = chai.spy.on(Item.database, 'query');

      return item.save({ in: 'go' })
        .then(function() {
          expect(spy).to.have.been.called.with(`INSERT INTO items
              (\`name\`)
              VALUES(?)`, 'go', [item.name]);
        });
    });

@vieiralucas
Copy link
Member

@xavicolomer are you sure that item.save is calling Item.database.query ?
Can you provide a more detailed example? Maybe a repo?

@xavicolomer
Copy link
Author

xavicolomer commented Sep 13, 2017

Yes it is called.

Please find below an extended version of the code above with the function. The queryReturnsInsert is logged correctly.

I also tried adding eventually (although since its inside then its already resolved)

it('test SQL',
    () => {
      const queryReturnsInsert = (arg1, arg2, arg3) => {
        console.log('Query arguments: ', arg1, arg2, arg3);
        return Promise.resolve({ insertId: 0 })
      };
      
      Item.database = { query: queryReturnsInsert };

      const item = new Item();
      item.name = 'James';

      const spy = chai.spy.on(Item.database, 'query');

      return item.save({ in: 'go' })
        .then(function() {
          expect(spy).to.have.been.called.with(`INSERT INTO items
              (\`name\`)
              VALUES(?)`, 'go', [item.name]);
        });
    });

then I get this error:

TypeError: { [Function]
  toString: [Function: toString],
  reset: [Function],
  __spy: { calls: [ [Object] ], called: true, name: undefined } } is not a thenable.

@xavicolomer
Copy link
Author

Since the database.query its abstract from the ORM, I can also simply kind of mock and save the arguments:

let _sql, _country, _values;

const queryReturnsInsert = (SQL, country, values) => {
  _sql = SQL;
  _country = country;
  _values = values;
  return Promise.resolve({ insertId: 0 })
};

And then:

expect(_sql).to.equal(`INSERT INTO items
              (\`custom_name\`)
              VALUES(?)`);

Although its not really clean

@stalniy
Copy link
Contributor

stalniy commented Jan 10, 2018

In order to check precise order of arguments you need to use .called.with.exactly()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants