numberkruncher
numberkruncher•3mo ago

How to mock modules like you can with jest?

With node/jest I was able to mock specific functions from modules using jest.mock at the start of the test file. How can I do this in Deno? I have a module which calls a function from another module:
import {foo} from "foo";

export function bar(a: number): number {
return foo(a * 2);
}
import {foo} from "foo";

export function bar(a: number): number {
return foo(a * 2);
}
How can I substitute foo with a mock/stub/fake for the scope of a test file?
jest.mock("foo", () => ({
foo: jest.fn();
}));

import {foo} from "foo";

describe("example", () => {
it("returns the expected number", () => {
foo.mockImplementation((_) => 100);
...
jest.mock("foo", () => ({
foo: jest.fn();
}));

import {foo} from "foo";

describe("example", () => {
it("returns the expected number", () => {
foo.mockImplementation((_) => 100);
...
2 Replies
Deno AI Helper
Deno AI Helper•3mo ago
In Deno, you can achieve similar functionality to jest.mock using the mocking utilities provided in the Deno standard library. The documentation describes two basic mock types: spy and stub, along with assertion functions dedicated to these types. A spy is a type of object that records every interaction with it, and you can assert an interaction occurred later. A stub is an object that simulates some predefined behavior. Here's an example of how you might use a spy to wrap a function:
import sinon from "npm:sinon";
import { assertEquals } from "https://deno.land/std@release-2024.05.07/assert/mod.ts";
import { bar, funcs } from "./my_module.js";

Deno.test("calls foo during execution of bar", () => {
// Create a test spy that wraps 'foo' on the 'funcs' object
const spy = sinon.spy(funcs, "foo");

// Call function 'bar' with an argument
bar(2);

// Assert that 'foo' was called with the expected argument
assertEquals(spy.calledWith(4), true);
});
import sinon from "npm:sinon";
import { assertEquals } from "https://deno.land/std@release-2024.05.07/assert/mod.ts";
import { bar, funcs } from "./my_module.js";

Deno.test("calls foo during execution of bar", () => {
// Create a test spy that wraps 'foo' on the 'funcs' object
const spy = sinon.spy(funcs, "foo");

// Call function 'bar' with an argument
bar(2);

// Assert that 'foo' was called with the expected argument
assertEquals(spy.calledWith(4), true);
});
In this example, funcs would be an object exported from my_module.js that contains the foo function you want to spy on. You would then import funcs and bar into your test file and create a spy on foo using sinon.spy. For stubbing, you can use the stub function from the Deno standard library's mocking utilities:
import {
returnsNext,
stub,
} from "https://deno.land/std@0.136.0/testing/mock.ts";
import { assertEquals } from "https://deno.land/std@0.136.0/testing/asserts.ts";

Deno.test("how stub works", () => {
const mathStub = stub(Math, "random", returnsNext([0.1, 0.2, 0.3]));
try {
assertEquals(Math.random(), 0.1);
assertEquals(Math.random(), 0.2);
assertEquals(Math.random(), 0.3);
} finally {
mathStub.restore();
}
});
import {
returnsNext,
stub,
} from "https://deno.land/std@0.136.0/testing/mock.ts";
import { assertEquals } from "https://deno.land/std@0.136.0/testing/asserts.ts";

Deno.test("how stub works", () => {
const mathStub = stub(Math, "random", returnsNext([0.1, 0.2, 0.3]));
try {
assertEquals(Math.random(), 0.1);
assertEquals(Math.random(), 0.2);
assertEquals(Math.random(), 0.3);
} finally {
mathStub.restore();
}
});
In your
Deno AI Helper
Deno AI Helper•3mo ago
case, you would create a stub for the foo function and then use it in your tests. Remember that you would need to export the object containing the foo function so that you can replace it with a stub in your tests. Please note that the examples provided here are based on the documentation and may require adjustments to fit the specific structure of your modules and tests. 🦕