testing/src/mock.test.ts

207 lines
4.6 KiB
TypeScript

import { describe, it } from "./blocks.ts";
import { expect } from "./assertions.ts";
import { mock, mockfn, patch } from "./mock.ts";
class Obj {
called = 0;
func(x: number) {
this.called += 1;
return x * 2;
}
}
function checkRestored(o: Obj) {
const called = o.called;
const result = o.func(4);
expect(o.called).toEqual(called + 1);
expect(result).toEqual(8);
}
describe("patch", () => {
it("calls through by default", () => {
const o = new Obj();
patch(o, "func", (mock) => {
const result = o.func(3);
expect(o.called).toEqual(1);
expect(result).toEqual(6);
expect(mock).toHaveBeenCalledTimes(1);
expect(mock).toHaveBeenCalledWith(3);
});
patch(o, "func", (mock) => {
const result = o.func(1);
expect(o.called).toEqual(2);
expect(result).toEqual(2);
expect(mock).toHaveBeenCalledTimes(1);
expect(mock).toHaveBeenCalledWith(1);
});
checkRestored(o);
});
it("calls sequential stubs before passing through", () => {
const o = new Obj();
patch(o, "func", (mock) => {
mock.stub((a) => a * 3);
mock.stub((a) => a * 4);
let result = o.func(2);
expect(result).toEqual(6);
result = o.func(2);
expect(result).toEqual(8);
expect(o.called).toEqual(0);
result = o.func(2);
expect(result).toEqual(4);
expect(o.called).toEqual(1);
expect(mock).toHaveBeenCalledTimes(3);
});
checkRestored(o);
});
it("calls stubs in loop", () => {
const o = new Obj();
patch(o, "func", (mock) => {
mock.stub((a) => a * 3, true);
let result = o.func(2);
expect(result).toEqual(6);
result = o.func(2);
expect(result).toEqual(6);
result = o.func(2);
expect(result).toEqual(6);
expect(o.called).toEqual(0);
expect(mock).toHaveBeenCalledTimes(3);
});
checkRestored(o);
});
it("can reset the mock", () => {
const o = new Obj();
patch(o, "func", (mock) => {
mock.stub((a) => a + 1, true);
let result = o.func(3);
expect(o.called).toEqual(0);
expect(result).toEqual(4);
expect(mock).toHaveBeenCalledTimes(1);
expect(mock).toHaveBeenCalledWith(3);
result = o.func(2);
expect(o.called).toEqual(0);
expect(result).toEqual(3);
expect(mock).toHaveBeenCalledTimes(2);
expect(mock).toHaveBeenCalledWith(2);
mock.reset();
mock.stub((a) => a + 10, true);
result = o.func(4);
expect(o.called).toEqual(0);
expect(result).toEqual(14);
expect(mock).toHaveBeenCalledTimes(1);
expect(mock).toHaveBeenCalledWith(4);
mock.reset();
result = o.func(4);
expect(o.called).toEqual(1);
expect(result).toEqual(8);
expect(mock).toHaveBeenCalledTimes(1);
expect(mock).toHaveBeenCalledWith(4);
});
checkRestored(o);
});
});
describe("mock", () => {
it("puts a no-op stub by default", () => {
const o = new Obj();
mock(o, "func", undefined, (mock) => {
let result = o.func(2);
expect(result).toBeUndefined();
expect(o.called).toEqual(0);
expect(mock).toHaveBeenCalledTimes(1);
});
checkRestored(o);
const f = mock(o, "func", undefined, () => o.func(2));
expect(f).toHaveBeenCalledTimes(1);
checkRestored(o);
});
it("stubs with a fixed value", () => {
const o = new Obj();
mock(o, "func", 17, (mock) => {
let result = o.func(2);
expect(result).toBe(17);
result = o.func(2);
expect(result).toBe(17);
expect(o.called).toEqual(0);
expect(mock).toHaveBeenCalledTimes(2);
});
checkRestored(o);
});
it("stubs with a function result", () => {
const o = new Obj();
let i = 9;
mock(o, "func", () => ++i, (mock) => {
let result = o.func(2);
expect(result).toBe(10);
result = o.func(2);
expect(result).toBe(11);
expect(o.called).toEqual(0);
expect(mock).toHaveBeenCalledTimes(2);
});
checkRestored(o);
});
});
describe("mockfn", () => {
it("constructs a simple mock function", () => {
let mock = mockfn();
expect(mock).toHaveBeenCalledTimes(0);
mock();
expect(mock).toHaveBeenCalledTimes(1);
mock = mockfn(() => 2);
expect(mock).toHaveBeenCalledTimes(0);
let result = mock();
expect(result).toEqual(2);
expect(mock).toHaveBeenCalledTimes(1);
result = mock();
expect(result).toEqual(2);
expect(mock).toHaveBeenCalledTimes(2);
mock = mockfn((x: number) => x + 1);
result = mock(5);
expect(result).toEqual(6);
expect(mock).toHaveBeenCalledTimes(1);
expect(mock).toHaveBeenCalledWith(5);
});
});