@@ -2048,6 +2048,87 @@ added:
20482048
20492049Resets the implementation of the mock module.
20502050
2051+ ## Class: ` MockPropertyContext `
2052+
2053+ <!-- YAML
2054+ added: REPLACEME
2055+ -->
2056+
2057+ The ` MockPropertyContext ` class is used to inspect or manipulate the behavior
2058+ of property mocks created via the [ ` MockTracker ` ] [ ] APIs.
2059+
2060+ ### ` ctx.accesses `
2061+
2062+ * {Array}
2063+
2064+ A getter that returns a copy of the internal array used to track accesses (get/set) to
2065+ the mocked property. Each entry in the array is an object with the following properties:
2066+
2067+ * ` type ` {string} Either ` 'get' ` or ` 'set' ` , indicating the type of access.
2068+ * ` value ` {any} The value that was read (for ` 'get' ` ) or written (for ` 'set' ` ).
2069+ * ` stack ` {Error} An ` Error ` object whose stack can be used to determine the
2070+ callsite of the mocked function invocation.
2071+
2072+ ### ` ctx.accessCount() `
2073+
2074+ * Returns: {integer} The number of times that the property was accessed (read or written).
2075+
2076+ This function returns the number of times that the property was accessed.
2077+ This function is more efficient than checking ` ctx.accesses.length ` because
2078+ ` ctx.accesses ` is a getter that creates a copy of the internal access tracking array.
2079+
2080+ ### ` ctx.mockImplementation(value) `
2081+
2082+ * ` value ` {any} The new value to be set as the mocked property value.
2083+
2084+ This function is used to change the value returned by the mocked property getter.
2085+
2086+ ### ` ctx.mockImplementationOnce(value[, onAccess]) `
2087+
2088+ * ` value ` {any} The value to be used as the mock's
2089+ implementation for the invocation number specified by ` onAccess ` .
2090+ * ` onAccess ` {integer} The invocation number that will use ` value ` . If
2091+ the specified invocation has already occurred then an exception is thrown.
2092+ ** Default:** The number of the next invocation.
2093+
2094+ This function is used to change the behavior of an existing mock for a single
2095+ invocation. Once invocation ` onAccess ` has occurred, the mock will revert to
2096+ whatever behavior it would have used had ` mockImplementationOnce() ` not been
2097+ called.
2098+
2099+ The following example creates a mock function using ` t.mock.property() ` , calls the
2100+ mock property, changes the mock implementation to a different value for the
2101+ next invocation, and then resumes its previous behavior.
2102+
2103+ ``` js
2104+ test (' changes a mock behavior once' , (t ) => {
2105+ const obj = { foo: 1 };
2106+
2107+ const prop = t .mock .property (obj, ' foo' , 5 );
2108+
2109+ assert .strictEqual (obj .foo , 5 );
2110+ prop .mock .mockImplementationOnce (25 );
2111+ assert .strictEqual (obj .foo , 25 );
2112+ assert .strictEqual (obj .foo , 5 );
2113+ });
2114+ ```
2115+
2116+ #### Caveat
2117+
2118+ For consistency with the rest of the mocking API, this function treats both property gets and sets
2119+ as accesses. If a property set occurs at the same access index, the "once" value will be consumed
2120+ by the set operation, and the mocked property value will be changed to the "once" value. This may
2121+ lead to unexpected behavior if you intend the "once" value to only be used for a get operation.
2122+
2123+ ### ` ctx.resetAccesses() `
2124+
2125+ Resets the access history of the mocked property.
2126+
2127+ ### ` ctx.restore() `
2128+
2129+ Resets the implementation of the mock property to its original behavior. The
2130+ mock can still be used after calling this function.
2131+
20512132## Class: ` MockTracker `
20522133
20532134<!-- YAML
@@ -2252,6 +2333,43 @@ test('mocks a builtin module in both module systems', async (t) => {
22522333});
22532334```
22542335
2336+ ### ` mock.property(object, propertyName[, value]) `
2337+
2338+ <!-- YAML
2339+ added: REPLACEME
2340+ -->
2341+
2342+ * ` object ` {Object} The object whose value is being mocked.
2343+ * ` propertyName ` {string|symbol} The identifier of the property on ` object ` to mock.
2344+ * ` value ` {any} An optional value used as the mock value
2345+ for ` object[propertyName] ` . ** Default:** The original property value.
2346+ * Returns: {Proxy} A proxy to the mocked object. The mocked object contains a
2347+ special ` mock ` property, which is an instance of [ ` MockPropertyContext ` ] [ ] , and
2348+ can be used for inspecting and changing the behavior of the mocked property.
2349+
2350+ Creates a mock for a property value on an object. This allows you to track and control access to a specific property,
2351+ including how many times it is read (getter) or written (setter), and to restore the original value after mocking.
2352+
2353+ ``` js
2354+ test (' mocks a property value' , (t ) => {
2355+ const obj = { foo: 42 };
2356+ const prop = t .mock .property (obj, ' foo' , 100 );
2357+
2358+ assert .strictEqual (obj .foo , 100 );
2359+ assert .strictEqual (prop .mock .accessCount (), 1 );
2360+ assert .strictEqual (prop .mock .accesses [0 ].type , ' get' );
2361+ assert .strictEqual (prop .mock .accesses [0 ].value , 100 );
2362+
2363+ obj .foo = 200 ;
2364+ assert .strictEqual (prop .mock .accessCount (), 2 );
2365+ assert .strictEqual (prop .mock .accesses [1 ].type , ' set' );
2366+ assert .strictEqual (prop .mock .accesses [1 ].value , 200 );
2367+
2368+ prop .mock .restore ();
2369+ assert .strictEqual (obj .foo , 42 );
2370+ });
2371+ ```
2372+
22552373### ` mock.reset() `
22562374
22572375<!-- YAML
@@ -3790,6 +3908,7 @@ Can be used to abort test subtasks when the test has been aborted.
37903908[ `--test-update-snapshots` ] : cli.md#--test-update-snapshots
37913909[ `--test` ] : cli.md#--test
37923910[ `MockFunctionContext` ] : #class-mockfunctioncontext
3911+ [ `MockPropertyContext` ] : #class-mockpropertycontext
37933912[ `MockTimers` ] : #class-mocktimers
37943913[ `MockTracker.method` ] : #mockmethodobject-methodname-implementation-options
37953914[ `MockTracker` ] : #class-mocktracker
0 commit comments