I have a mock and want to make sure that it was called with a specific set of arguments. However, I do not want to loop through all calls first.
it("should assert args", (t) => {
const loggerSpy = t.mock.method(Logger, "info");
myFunctionUnderTest();
// this will obivously not work
assert.deepStrictEqual(loggerInfoSpy.mock.calls, { arguments: [2, "No consumer application for given code", "MODEL_ENERGY_FLOW"] });
})
Is there a way to have an assertion like this? Basically I want to have something that would look in jest like this:
expect(
loggerInfoSpy.mock.calls
).toEqual(
expect.arrayContaining(
[{ arguments: [2, "No consumer application for given code", "MODEL_ENERGY_FLOW"] }]
)
);
Even better ofcourse would be an assertion similar to expect(loggerInfoSpy).toHaveBeenCalledWith(...)
.
Is there any way to add assertions / extend the node:assert
module?
You'll have to create your own helper function to do this, you can attach it to the assert module yourself if you wish. Here's an example:
const { describe, it, before } = require('node:test'),
{ isDeepStrictEqual } = require('node:util'),
assert = require('node:assert');
assert.calledWith = function(calls, chk) {
if(calls.mock)
calls = calls.mock.calls;
else if(calls.calls)
calls = calls.calls;
for(let call of calls) {
if(isDeepStrictEqual(call.arguments, chk))
return true;
}
assert.fail(`Expected function to be called with ${JSON.stringify(chk)}`);
}
class Foo {
bar(a,b,c) {
}
}
describe('foo', function() {
let foo;
before(function(t) {
foo = new Foo();
});
it('expect pass', (t) => {
let spy = t.mock.method(foo,'bar');
let args = [ 'asdfa', 24342, {x:'y'} ];
foo.bar(...args);
assert.calledWith(spy,args);
});
it('expect fail', (t) => {
let spy = t.mock.method(foo,'bar');
let args = [ 'asdfa', 24342, {x:'y'} ];
foo.bar(...args);
assert.calledWith(spy,args.reverse());
});
});
▶ foo
✔ expect pass (0.588027ms)
✖ expect fail (0.490436ms)
AssertionError [ERR_ASSERTION]: Expected function to be called with [{"x":"y"},24342,"asdfa"]
at assert.calledWith (/tmp/foo/test.js:15:10)
at TestContext.<anonymous> (/tmp/foo/test.js:38:12)
at Test.runInAsyncScope (node:async_hooks:206:9)
at Test.run (node:internal/test_runner/test:631:25)
at async Suite.processPendingSubtests (node:internal/test_runner/test:374:7) {
generatedMessage: false,
code: 'ERR_ASSERTION',
actual: undefined,
expected: undefined,
operator: 'fail'
}
▶ foo (2.386671ms)
ℹ tests 2
ℹ suites 1
ℹ pass 1
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 8.105062
✖ failing tests:
test at test.js:34:3
✖ expect fail (0.490436ms)
AssertionError [ERR_ASSERTION]: Expected function to be called with [{"x":"y"},24342,"asdfa"]
at assert.calledWith (/tmp/foo/test.js:15:10)
at TestContext.<anonymous> (/tmp/foo/test.js:38:12)
at Test.runInAsyncScope (node:async_hooks:206:9)
at Test.run (node:internal/test_runner/test:631:25)
at async Suite.processPendingSubtests (node:internal/test_runner/test:374:7) {
generatedMessage: false,
code: 'ERR_ASSERTION',
actual: undefined,
expected: undefined,
operator: 'fail'
}