question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Proposal: partialMocked - mocked, but less strict return/resolved values.

See original GitHub issue

Issue :

I want to do something like this…

const mockFoo = mocked(foo);
mockFoo.mockReturnValue({
  valueNeededForTest: 'string' // TypeScript mad! foo returns other values too!
});

But because foo returns a dozen other properties that the test doesn’t rely on, so we get errors like this:

Error:(21, 43) TS2345: Argument of type '{ valueNeededForTest: string }' is not assignable to parameter of type '{ buildPath: string; babelReactIntlPath:
string; cachePath: string; coveragePath: string; isCI: boolean; githubHostname: string; githubOrg: string; githubRepo: string; localPublicPath: string; ... 7 more ...; getPathWithoutRepoDirectory: 
(pathToShorten: string) => string; }'.
Type '{ valueNeededForTest: string; }' is missing the following properties from type '{ buildPath: string; babelReactIntlPath: string; cachePath: string; 
coveragePath: string; isCI: boolean; githubHostname: string; githubOrg: string; githubRepo: string; localPublicPath: string; ... 7 more ...; 
getPathWithoutRepoDirectory: (pathToShorten: string) => string; }': buildPath, babelReactIntlPath, cachePath, coveragePath, and 12 more.

Workarounds:

This takes away the nice typing mocked provides:

const mockFoo = mocked(foo);
mockFoo.mockReturnValue(({
  valueNeededForTest: 'string'
} as unknown) as ReturnType<foo>);

This isn’t always possible, as running the original function can have side effects, or return something that can’t be easily merged like a promise, and jest.requireActual’s return type is any so it doesn’t even solve the original problem.

const mockFoo = mocked(foo);
mockFoo.mockReturnValue({
  ...jest.requireActual('./foo'),
  valueNeededForTest: 'string'
});

Preferred behavior :

A new function called partialMocked (maybe there’s a better name?) that allows returnType/resolvedValue/etc to be a deep partial of what it normally returns.

const mockFoo = partialMocked(foo);
mockFoo.mockReturnValue({
  valueNeededForTest: 'string' // TypeScript happy, developer happy!
});

Example implementation :

type DeepPartial<T> = {
    [P in keyof T]?: T[P] extends Array<infer U>
        ? Array<DeepPartial<U>>
        : T[P] extends ReadonlyArray<infer U>
            ? ReadonlyArray<DeepPartial<U>>
            : DeepPartial<T[P]>
};

type PartialReturnType<T extends MockableFunction> = 
    ReturnType<T> extends Promise<infer U>
        ? Promise<DeepPartial<U>>
        : ReturnType<T> extends Array<infer P>
            ? Array<DeepPartial<P>>
            : DeepPartial<ReturnType<T>>;

interface MockWithArgs<T extends MockableFunction> extends jest.MockInstance<PartialReturnType<T>, ArgumentsOf<T>> {
    new (...args: ConstructorArgumentsOf<T>): T;
    (...args: ArgumentsOf<T>): PartialReturnType<T>;
}

This fixed the issues I was having. I’m still fairly new with TypeScript, so I’m not sure if this is a complete solution or the right way to do it, so that’s why I made this ticket instead of starting with a pull request.

Thoughts?

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:10
  • Comments:5

github_iconTop GitHub Comments

2reactions
ahnpnlcommented, Apr 16, 2019

there is a discussion about mock utils in #1048 . If jest team agrees to migrate mock utils to jest repo, perhaps this proposal can go into jest repo.

0reactions
sbycroszcommented, Sep 27, 2022

I have pasted this issue on https://github.com/facebook/jest/issues/13325. Hopefully, it will be picked up 🥲

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to allow partial TypeScript types when mocking functions
I suspect there is some way to use a partial type here to allow better and more useful mocking by overriding the return...
Read more >
Creating Partial Mocks - Mockery Docs
Partial mocks are useful when we only need to mock several methods of an object leaving the remainder free to respond to calls...
Read more >
Mockito (Mockito 4.10.0 API) - javadoc.io
You can create a mock with specified strategy for its return values. It's quite an advanced feature and typically you don't need it...
Read more >
gMock for Dummies | GoogleTest
A mock object implements the same interface as a real object (so it can be used as one), but lets you specify at...
Read more >
Interaction Based Testing - Spock Framework
Conversely, mocking frameworks like EasyMock and JMock are strict by default ... value for the method's return type ( false , 0 ,...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found