diff --git a/_e2e/fn_test.ts b/_e2e/fn_test.ts
index acfd827..8a7fc66 100644
--- a/_e2e/fn_test.ts
+++ b/_e2e/fn_test.ts
@@ -1,5 +1,5 @@
// Copyright 2021-Present the Unitest authors. All rights reserved. MIT license.
-import { expect, fn, test } from "../mod.ts";
+import { expect, fn, isMockObject, test } from "../mod.ts";
test("should define implementation as default", () => {
const mockObject = fn().defaultImplementation(() => true);
@@ -66,3 +66,9 @@ test("should clear mock and all registered once implementations and default", ()
mockObject();
expect(mockObject).toHaveReturnedWith(undefined);
});
+
+test("should be mock object", () => {
+ const mockObject = fn();
+ expect(isMockObject(mockObject)).toBeTruthy();
+ expect(isMockObject({})).toBeFalsy();
+});
diff --git a/mock/README.md b/mock/README.md
index b59b1cb..8e6520e 100644
--- a/mock/README.md
+++ b/mock/README.md
@@ -42,6 +42,25 @@ test("plays video", () => {
});
```
+## isMockObject
+
+Whatever argument is `MockObject` or not.
+
+```ts
+import {
+ expect,
+ fn,
+ isMockObject,
+ test,
+} from "https://deno.land/x/unitest@$VERSION/mod.ts";
+
+test("should be mock object", () => {
+ const mockObject = fn();
+ expect(isMockObject(mockObject)).toBeTruthy();
+ expect(isMockObject({})).toBeFalsy();
+});
+```
+
## mockObject.mock.calls
An array containing the call arguments of all calls that have been made to this
diff --git a/mock/fn.ts b/mock/fn.ts
index c3d57be..3b37a5a 100644
--- a/mock/fn.ts
+++ b/mock/fn.ts
@@ -1,6 +1,8 @@
// Copyright 2021-Present the Unitest authors. All rights reserved. MIT license.
// This module is browser compatible.
+import { isObject } from "../deps.ts";
+import { prop } from "../matcher/utils.ts";
import { Mock } from "./mock.ts";
import type { MockSpec } from "./mock.ts";
import { incrementalNumber } from "./utils.ts";
@@ -328,5 +330,32 @@ function fn(
return call as MockObject;
}
-export { fn, MockFnStore };
+/** Whatever argument is `MockObject` or not.
+ * ```ts
+ * import {
+ * expect,
+ * fn,
+ * isMockObject,
+ * test,
+ * } from "https://deno.land/x/unitest@$VERSION/mod.ts";
+ *
+ * test("should be mock object", () => {
+ * const mockObject = fn();
+ * expect(isMockObject(mockObject)).toBeTruthy();
+ * expect(isMockObject({})).toBeFalsy();
+ * });
+ * ```
+ */
+function isMockObject(
+ value: object,
+): value is MockObject {
+ const mock = prop("mock", value);
+ if (!isObject(mock)) return false;
+
+ return ["results", "calls", "callOrderNumbers"].every((key) =>
+ Array.isArray(prop(key, mock))
+ );
+}
+
+export { fn, isMockObject, MockFnStore };
export type { MockObject };
diff --git a/mock/fn_test.ts b/mock/fn_test.ts
index 7378b09..98e66f6 100644
--- a/mock/fn_test.ts
+++ b/mock/fn_test.ts
@@ -1,6 +1,6 @@
// Copyright 2021-Present the Unitest authors. All rights reserved. MIT license.
-import { fn, MockFnStore } from "./fn.ts";
+import { fn, isMockObject, MockFnStore } from "./fn.ts";
import { isFunction } from "../deps.ts";
import { expect } from "../expect/mod.ts";
import { assert, assertEquals, assertExists } from "../dev_deps.ts";
@@ -314,3 +314,42 @@ Deno.test("reset should clear once implementation and default", () => {
assertEquals(mockObject(), undefined);
assertEquals(mockObject(), undefined);
});
+
+Deno.test("isMockObject", () => {
+ const table: [
+ ...Parameters,
+ ReturnType,
+ ][] = [
+ [{}, false],
+ [[], false],
+ [{ mock: {} }, false],
+ [{
+ mock: {
+ results: [],
+ callOrderNumbers: [],
+ },
+ }, false],
+ [{
+ mock: {
+ callOrderNumbers: [],
+ },
+ }, false],
+ [{
+ mock: {
+ calls: [],
+ results: [],
+ callOrderNumbers: [],
+ },
+ }, true],
+ [{
+ mock: {
+ calls: [[1]],
+ results: [{ type: "return", value: 1 }],
+ callOrderNumbers: [1],
+ },
+ }, true],
+ [fn(), true],
+ ];
+
+ table.forEach(([value, result]) => assertEquals(isMockObject(value), result));
+});