Coder Social home page Coder Social logo

jest-when's People

Contributors

aleonov-virtru avatar andrewsouthpaw avatar benjaminjkraft avatar chyzwar avatar dependabot[bot] avatar devzeebo avatar ebaumqb avatar haines avatar idan-at avatar jeyj0 avatar jlissner avatar jozzi05 avatar mircohacker avatar quassnoi avatar timkindberg avatar tjenkinson avatar whoaa512 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

jest-when's Issues

Feature request: support function overloading

Hey!

While using this lib with TypeORM, I'm facing this limitation for function overloading.

Let's say I want to mock a call for repository.findOne method which have 3 overloads. I'll get this:

ts error

since jest-when only recognize the last overload of .findOne which is findOne(conditions?: FindConditions<Entity>, options?: FindOneOptions<Entity>) and I'm using the first one (which is findOne(id?: string|number|Date|ObjectID, options?: FindOneOptions<Entity>)) ๐Ÿ˜•

Is there any know workaround for this? Meanwhile I'm using //@ts-expect-error

Great lib btw!

Promise rejection was handled asynchronously

(node:16003) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 1) at handledRejection

In my test, I mock rejected value without calledWith, then I get the errors.

  when(mockFn)
    .mockRejectedValue({})

If I make it with calledWith, it works:

  when(mockFn)
    .calledWith(expect.anything())
    .mockRejectedValue({})

I get this error then I change jest-when CODE from

    this.mockResolvedValue = returnValue => this.mockReturnValue(Promise.resolve(returnValue))
    this.mockRejectedValue = err => this.mockReturnValue(Promise.reject(err))

to

    this.mockResolvedValue = returnValue => this.mockImplementation(() => Promise.resolve(returnValue))
    this.mockRejectedValue = err => this.mockImplementation(() => Promise.reject(err))

It seems work. I think that because Promise computed too early. Is that right?

Partial function signature matching

Could there be a workaround for having a partial argument signature matching? Let me illustrate this.

when(method)
      .calledWith(
         foobar, 
         foo, 
         bar, 
         baz, 
         qux, 
         quux, 
         quuz
      )
      .mockReturnValue('Yaaai!);

Instead of having this long calledWith, to use the same concept as C# uses when testing with It.Is to transform the above code into something like:

when(method)
      .calledWithPartial( {
             foobarArg: foobar,
             quxArg: qux
         }
      )
      .mockReturnValue('Yaaai!);

This way, you wouldn't need to worry about matching the exact signature over and over, only the variables that matter to you.
I just put the very first method name that popped into my head, but it can most definitely be improved for sure.

Maybe there's an easier way with jest.Any(constructor) but I'm not sure.

Could this thing be achievable?

Using a default value does not update the whenified implementation

Sample code:

const { when } = require('jest-when')

it('allows defining the default when NOT chaining', () => {
  const fn = jest.fn()

  when(fn).mockRejectedValue(false)

  when(fn)
    .calledWith(expect.anything())
    .mockResolvedValue(true)

  expect(fn()).rejects.toEqual(false)
});

Expectation: The test case to pass

Object matchers should be strict

When I set up the following:

when(get).expectCalledWith({ name: "test" }).mockResolvedValueOnce({});

I expect this to throw:

get({ name: "test", age: 21, height: 190 });

Are there any workarounds for this?

mockReset doesn't play nicely with jest-when

Had a bit of bother with using jest-when this afternoon. Basically the following code triggers the issue:

const { when } = require('jest-when')
const testFn = jest.fn()

describe('testing', () => {
  afterEach(() => {
    testFn.mockReset()
  })

  test('test1', () => {
    when(testFn)
      .calledWith('test')
      .mockReturnValueOnce(1)
      .mockReturnValueOnce(2)
      .mockReturnValueOnce(3)
    expect(testFn('test')).toBe(1)
    expect(testFn.mock.calls.length).toBe(1)
  })

  test('test2', () => {
    when(testFn).calledWith('test').mockReturnValueOnce(1)
    expect(testFn('test')).toBe(1)
    expect(testFn.mock.calls.length).toBe(1)
  })
})

So in the code above I setup two tests and run them with jest. I set it so that the function I'll be mocking (a dummy function testFn) is reset by .mockReset in the afterEach so I know setup from one test won't bleed into the other.

I setup test1 to have three values that get returned on calls but I only use one of them. After test1 has ran I expect test2 to not have anything associated with the mock. However if you run the above, rather than getting 1 as I expect I get 2 from test1. This doesn't happen if I don't add further return values, then I get nothing (as expected).

I can get around this by adding the following line, however I shouldn't have to and this caused me a lot of problems tracking down errors this afternoon.

  afterEach(() => {
    testFn.mockReset()
    testFn.__whenMock__ = undefined
  })

calledWith with functions arguments not recognized

I have this function

  watchDataInformationRequests(
    sortFn?: (a: DataInformationRequest, b: DataInformationRequest) => number
  ): Observable<DataInformationRequest[]> {
    return this.store.select(RequestsState.dataInformationRequests(sortFn));
  }

and I want to mock the store.select when it receives a RequestsState.dataInformationRequests(sortFn).

I tried:

const fromNewestToOldest = (a: { createdAt: Date }, b: { createdAt: Date }) =>
  b.createdAt.getTime() - a.createdAt.getTime();

when(store.select)
  .calledWith(RequestsState.dataInformationRequests(fromNewestToOldest))
  .mockReturnValue(of(sortedRequests));
when(store.select)
  .calledWith(RequestsState.dataInformationRequests(expect.anything()))
  .mockReturnValue(of(sortedRequests));
when(store.select)
   .calledWith(expect.any(RequestsState.dataInformationRequests))
  .mockReturnValue(of(sortedRequests));
when(store.select)
  .calledWith(RequestsState.dataInformationRequests)
  .mockReturnValue(of(sortedRequests));

In all the cases, when I call watchDataInformationRequests the when is not recognized, and it returns null.

I am trying to do an integration test, so I cannot just mock watchDataInformationRequests.

I tried mocking store.select directly, and in that case it works, so I imagine that the problem comes from when not being able to properly compare that the functions are the same, or I am providing the wrong value to when.

How can I mock a function when it expects another function as argument?

Fix: interoperability with @golevelup/ts-jest

Hi! ๐Ÿ‘‹

I had a problem using createMock from @golevelup/ts-jest because it uses proxies to fake properties, and the test below against _isAllArgsFunctionMatcher gives a false positive (returns a jest.fn() instance).

Here is the diff that solved my problem:

diff --git a/node_modules/jest-when/src/when.js b/node_modules/jest-when/src/when.js
index 760b9bb..b7590bc 100644
--- a/node_modules/jest-when/src/when.js
+++ b/node_modules/jest-when/src/when.js
@@ -93,7 +93,7 @@ class WhenMock {
 
           let isMatch = false
 
-          if (matchers && matchers[0] && matchers[0]._isAllArgsFunctionMatcher) {
+          if (matchers && matchers[0] && (typeof matchers[0] === 'function' || typeof matchers[0] === 'object') && '_isAllArgsFunctionMatcher' in matchers[0] && matchers[0]._isAllArgsFunctionMatcher) {
             if (matchers.length > 1) throw new Error('When using when.allArgs, it must be the one and only matcher provided to calledWith. You have incorrectly provided other matchers along with when.allArgs.')
             isMatch = checkArgumentMatchers(expectCall, [args])(true, matchers[0], 0)
           } else {

How to use with mock modules?

I mock a module like so:

const { aMethodInTheModule } = require('./myModule');

jest.mock('./myModule', () => ({
  aMethodInTheModule: jest.fn(),
}));

Then, the below code doesn't works:

when(aMethodInTheModule)
  .calledWith('a')
  .mockReturnValue(() => Promise.resolve('b'));

Document that when accepts the output of jest.spyOn

It works now, I'm just adding the tests and documentation for that in a PR.

Types are broken at the moment in @typed/jest-when (as far as TypeScript is concerned, the output of jest.spyOn is not a valid input for when).

We need to document that it works, so that I could link documentation in a PR to DefinitelyTyped.

No longer working with the latest version of Jest and TypeScript

Description

Given the following code:

import { jest } from "@jest/globals";
import type { SpyInstance } from "jest-mock";
import type { ExecSyncOptions } from "node:child_process";

import { isInGitRepository } from "../../src/helpers/git";

describe("tests", function () {
  let execSyncMock: SpyInstance<string | Buffer, [command: string, options?: ExecSyncOptions | undefined]>;

  beforeEach(function () {
    when(execSyncMock)
      .calledWith("git rev-parse --is-inside-work-tree", { stdio: "ignore" })
      .mockImplementationOnce(function () {
        throw new Error();
      });
  });

  test("it returns false", function () {
    expect(isInGitRepository()).toBe(false);
  });
});

The TypeScript compilation fails with the following error:

Argument of type 'SpyInstance<string | Buffer, [command: string, options?: ExecSyncOptions | undefined]>' is not assignable to parameter of type '((command: string, options?: ExecSyncOptions | undefined) => unknown) | MockInstance<unknown, [command: string, options?: ExecSyncOptions | undefined]>'.
  Type 'SpyInstance<string | Buffer, [command: string, options?: ExecSyncOptions | undefined]>' is not assignable to type 'MockInstance<unknown, [command: string, options?: ExecSyncOptions | undefined]>'.
    The types of 'mock.results' are incompatible between these types.
      Type 'MockFunctionResult[]' is not assignable to type 'MockResult<unknown>[]'.
        Type 'MockFunctionResult' is not assignable to type 'MockResult<unknown>'.
          Type 'MockFunctionResult' is not assignable to type 'MockResultReturn<unknown>'.
            Types of property 'type' are incompatible.
              Type 'MockFunctionResultType' is not assignable to type '"return"'.
                Type '"throw"' is not assignable to type '"return"'.ts(2345)

Environment

Feature request: calledWith() should accept RegEx when argument is a string

Context:

  • Firebase Firestore
  • Typescript
  • Jest v27

I am trying to stub out calls to my database in my tests to return a specific object, this is what the code looks like:

const authToken = { /* ... */ };
 when(db.getById)
  .calledWith(`/users/${userId}/privateData/twitterToken`)
   .mockResolvedValue(authToken);

However I'm finding this a bit too rigid, as in some cases I don't have the userId since a fake user instance is used to authenticate. It requires me to do some weird manipulations in order to make the tests work. It would be neat if we could do something like this:

const authToken = { /* ... */ };
 when(db.getById)
  .calledWithRegEx(/privateData\/twitterToken/)
   .mockResolvedValue(authToken);

In this way, any calls to db.getById that matches my regex would receive the authToken mocked value, without having to be too granular/specific.
This also applies really well when you have to provide a URL as a parameter, or some other long string literal that contains dynamic values.

"Overloaded" default mock

Hey! Just found this library, very nice utility.

I'd love a way to set up a "default" mock using jest-when. For example:

when(getUser).calledWith(expect.anything()).mockResolvedValue(null);
when(getUser).calledWith(1).mockResolvedValue(userFixture);

But this does not seem to work. The expect.anything() does not seem to work. It works if I only have it, but not in combination with the "real" mock.

As a workaround, I have to specify the "incorrect" user ID that I use in my test, but I would love to not have to do that:

when(getUser).calledWith(666).mockResolvedValue(null);
when(getUser).calledWith(1).mockResolvedValue(userFixture);

Support for expecting / asserting `this` argument

When I mock one function in MyClass.prototype, I would like to assert and expect that the mock was called with the correct this value (on a particular instance).

AFAIU there is no possibility for that now โ€“ but it would be a really nice functionality to have.

Or are there any ways to achieve that in the current version?

How might we utilize snapshots for arguments matching?

I have a use case where I'm generating a relatively large payload and I'd like when to make a snapshot for one of the arguments.

Example code

import { when } from 'jest-when'

const fn = jest.fn()

test('match snap', () => {
    expect.hasAssertions()

    when(fn)
        .expectCalledWith(expect.toMatchSnapshot())
        .mockReturnValueOnce('hi')

    expect(fn({ bar: { a: 12 } })).toEqual('hi')
})

Basically I want to jest-when to look at the arg and if I pass the asymmetric snapshot matcher to use expect(arg).toMatchSnapshot() instead of the normal .toEqual

What do you think?

For context, expect.toMatchSnapshot() is only available in jest 23+, and even then expect.toMatchSnapshot() doesn't actually work like you'd expect.

Allow interchangeable usage of `calledWith` and `expectCalledWith`

I am seeing several oddities with jest-when that I can't easily explain. Many of them surfaces, when I use expectCalledWith.

Synchronous straight-forward call

For example:

This works

const { when } = require('jest-when');
test.only('test when', () => {
    const fn = jest.fn()
    when(fn).calledWith(1).mockReturnValue(1)
    when(fn).calledWith(2).mockReturnValue(2)
    when(fn).calledWith(3).mockReturnValue(3)

    fn(1)
    fn(2)
    fn(3)

    expect(fn).toBeCalledTimes(3)
})

This doesn't work, claiming that fn(2) expected 1 as a argument

const { when } = require('jest-when');
test.only('test when', () => {
    const fn = jest.fn()
    when(fn).expectCalledWith(1).mockReturnValue(1)
    when(fn).expectCalledWith(2).mockReturnValue(2)
    when(fn).expectCalledWith(3).mockReturnValue(3)

    fn(1)
    fn(2)
    fn(3)

    expect(fn).toBeCalledTimes(3)
})

Asynchronous call with mixed order

What's more, I had a similar problem in my production code, where I had fetch module mocked and tried to describe it's behaviour. And it was working as expected only when I used calledWith or when I used when(fetch).expectCalledWith in the exact order of the calls (which is not desired, as a function call order in my case is interchangeable.)

**so this will work: **
notice the order of when.calledWith arguments ("url3", "url2", "url1")

const { when } = require('jest-when');
test.only('test when fetch', async () => {
    const fetch = require('node-fetch');

    when(fetch)
        .calledWith(expect.stringContaining(`url3`))
        .mockReturnValueOnce(Promise.resolve(new Response(`3`)))

    when(fetch)
        .calledWith(expect.stringContaining(`url2`))
        .mockReturnValueOnce(Promise.resolve(new Response(`2`)))

    when(fetch)
        .calledWith(expect.stringContaining(`url1`))
        .mockReturnValueOnce(Promise.resolve(new Response(`1`)))

    await (async () => {
        let res1 = await fetch(`http://url1`)
        expect(await res1.json()).toBe(1)
        let res2 = await fetch(`http://url2`)
        expect(await res2.json()).toBe(2)
        let res3 = await fetch(`http://url3`)
        expect(await res3.json()).toBe(3)
    })()

    expect(fetch).toBeCalledTimes(3)
})

and this will work:
notice the order of when.expectCalledWith arguments ("url1", "url2", "url3")

const { when } = require('jest-when');
test.only('test when fetch', async () => {
    const fetch = require('node-fetch');

    when(fetch)
        .expectCalledWith(expect.stringContaining(`url1`))
        .mockReturnValueOnce(Promise.resolve(new Response(`1`)))

    when(fetch)
        .expectCalledWith(expect.stringContaining(`url2`))
        .mockReturnValueOnce(Promise.resolve(new Response(`2`)))

    when(fetch)
        .expectCalledWith(expect.stringContaining(`url3`))
        .mockReturnValueOnce(Promise.resolve(new Response(`3`)))

    await (async () => {
        let res1 = await fetch(`http://url1`)
        expect(await res1.json()).toBe(1)
        let res2 = await fetch(`http://url2`)
        expect(await res2.json()).toBe(2)
        let res3 = await fetch(`http://url3`)
        expect(await res3.json()).toBe(3)
    })()

    expect(fetch).toBeCalledTimes(3)
})

but this will fail:
notice the order of when.expectCalledWith arguments ("url3", "url2", "url1")

const { when } = require('jest-when');
test.only('test when fetch', async () => {
    const fetch = require('node-fetch');

    when(fetch)
        .expectCalledWith(expect.stringContaining(`url3`))
        .mockReturnValueOnce(Promise.resolve(new Response(`3`)))
        
    when(fetch)
        .expectCalledWith(expect.stringContaining(`url2`))
        .mockReturnValueOnce(Promise.resolve(new Response(`2`)))

    when(fetch)
        .expectCalledWith(expect.stringContaining(`url1`))
        .mockReturnValueOnce(Promise.resolve(new Response(`1`)))


    await (async () => {
        let res1 = await fetch(`http://url1`)
        expect(await res1.json()).toBe(1)
        let res2 = await fetch(`http://url2`)
        expect(await res2.json()).toBe(2)
        let res3 = await fetch(`http://url3`)
        expect(await res3.json()).toBe(3)
    })()

    expect(fetch).toBeCalledTimes(3)
})

In both cases, I'd expect the expectCalledWith to work the same way as calledWith, except that expectCalledWith would fail the test if given call did not occur. So I expect that all the above examples should work.

Am I missing some trick I should apply in those cases?

The fact that the sync and the async calls are behaving differently seems to me like a straight-forward bug.

The async call scenario is missing order-agnostic and order-aware expectCalled... versions, so this from the outside looks like a feature I'd appreciate.

I reported both in here as they seem to be somewhat related - feel free to correct me, I can split it always into separate issues.

make jest/expect an peer deps?

Currently jest-when use expect v24, unless user of library also use jest v24 whole swats of jest specific dependencies are duplicated.
I suggest that jest-when declare jest as peer dep with version like "jest": ">= 24"

expect.assertions(1) doesn't work with v3.4.1

Hey, after updating to v3.4.1, this code starts to fail

const { when } = require("jest-when");

it('works', () => {
    expect.assertions(1);
    expect(true).toBe(true);
});

with:

 FAIL  ./test.js
  โœ• works (3 ms)

  โ— works

    expect.assertions(1)

    Expected one assertion to be called but received two assertion calls.

      2 |
      3 | it('works', () => {
    > 4 |     expect.assertions(1);
        |            ^
      5 |     expect(true).toBe(true);
      6 | });
      7 |

      at Object.<anonymous> (test.js:4:12)

Test Suites: 1 failed, 1 total

After removing the require the test passes.

Issues with Jest 28 version

It looks like this library will not work with Jest 28.

Cannot find module 'expect/build/jasmineUtils' from 'node_modules/jest-when/src/when.js'

    Require stack:
      node_modules/jest-when/src/when.js
      src/functions/public/exposed-objects/contact-collection/get-enriched-contacts.spec.ts

      at Resolver._throwModNotFoundError (node_modules/jest-resolve/build/resolver.js:491:11)
      at Object.<anonymous> (node_modules/jest-when/src/when.js:2:15)

Any plans to support that in the future or it's not gonna happen ?

Allow default return value other than undefined

Could there be a way to define the value that is always returned when no matches are made with calledWith. So being able to set something other than undefined:

  const mock = jest.fn();
  when(mock)
    .mockReturnValue('default') // always returned
    .calledWith('blah')
    .mockReturnValue('test'); // returned when `'blah'` is passed

Feature request: allow partial argument matches

overview

I'm a big fan of jest-when, and it makes using jest mocks far more pleasant than using them vanilla. I have a feature request (that I'd be very open to PR'ing, if you find it acceptable) to cover a particular usage that we've run into at my company.

Currently, calledWith requires all function arguments to be specified. For the vast majority of use cases, I think this is sensible and correct. I think there are, however, a small set of times when it would be nice to be able to omit arguments in the stub configuration, because they truly do not matter for the subject under test.

Would you be open to adding an option to allow extra arguments to be ignored?

const myDouble = jest.fn()

// potential APIs
// new method
when(myDouble).partiallyCalledWith("foo").mockReturnValue("bar")
// options object in when
when(myDouble, { ignoreExtraArgs: true }).calledWith("foo").mockReturnValue("bar")

assert(myDouble("foo") === "bar")
assert(myDouble("foo", "other", "stuff") === "bar")

risks and alternatives

  • Alternative: just use jest's asymmetric matchers
    • An expect.anything() or several could do the trick in most cases, at the expense of verbosity
  • Alternative: write your own mockImplementation for these use cases
  • Alternative: write a little when and calledWith wrapper and deal with the problem in userland
  • Risk: this would be a powerful feature that could be easily misused
    • I really misused Sinon's partial matching in my early days of learning how to mock
    • The default of this library is to require all arguments for a reason
  • Risk: maintenance burden

prior art

testdouble.js, which has a very similar API to jest-when and seems to me to come from the same stubbing lineage, has an ignoreExtraArgs option during stub configuration.

sinon.js does partial stubbing by default in its calledWith assertion. I think this is a bad default, but folks coming from Sinon would at least be familiar with this behavior.

(Edit) after a deeper issue search that I should've completed before hitting submit, I ran into #36. I think this request is related, but distinct, because I'm talking specifically about rare cases where trailing arguments have no meaning to the subject nor stub.

actual use case

In this particular case, we're mocking out React function components. We have a collaborator component, and we want to verify that some child component is properly arranged with the correct props:

import * as React from 'react'
import { when } from 'jest-when'
import { render, screen } from '@testing-library/react'
import { SomeChild } from './SomeChild'  // export const SomeChild = (props) => (<>{...}</>)
import { SomeParent } from './SomeParent'

jest.mock('./SomeChild')

describe('SomeParent component', () => {
  it('should pass xyz prop down to SomeChild', () => {
    when(ShomeChild).calledWith({ xyz: '123' }).mockReturnValue(<span>hello world</span>)

    render(<SomeParent xyz="123" />)
    expect(screen.getByText('hello world'))
  })
})

You (or rather, I) would expect this to work! However, it does not. For legacy reasons that have nothing to do with the code under test, the React rendering system passes two arguments the the SomeChild function, props, and something else called refOrContext. All of our function components are written to accept a single function parameter, props, so the fact that React is passing in a second parameter doesn't do anything because it's always ignored.

We can fix the test by doing...

when(ShomeChild)
  .calledWith({ xyz: '123' }, expect.anything())
  .mockReturnValue(<span>hello world</span>)

...but it's a little more verbose and, more importantly to me, muddies how the test communicates its intent to the reader

ES6 Class Support?

Thanks for creating this wonderful package! Absolutely loving it!

Any plan on supporting ES6 Class constructor? Something like the following?

when(Car)
  .constructWith('Mercedes')
  .mockInstance({
    color: 'red',
    price: 50,
  });

Just an idea! ๐Ÿ˜„

2.8 -> 3.2 mocking does not work on short-form abc.map(makeFoo)

import {makeFoo} from "foo"
import {when} from "jest-when"
when(makeFoo)
    .calledWith('bar')
    .mockReturnValue(123)

abc.map(makeFoo)              // mocking does not work
abc.map(x => makeFoo(x)) //  mocking works

Any idea why the short form mocking does not work with 3.2 ?

Allow setting default after training

Would it be possible to make it so that you could set or replace the default return value without also resetting previously-added training? Basically, could jest-when be modified to make the following test pass?

it('can add default after training, reduced', async () => {
  const fn = jest.fn();
  
  when(fn).calledWith(1).mockReturnValue('a');
  
  fn.mockReturnValue('b');
  
  expect(fn(1)).toEqual('a');
  expect(fn(2)).toEqual('b');
});

Run time error Node v14.17.0

I have used jest-when library to mock reading of a specific file like below
when(mockedReadFileSync).calledWith(path.resolve(__dirname, "./../../assets/settings.json"), { encoding: "utf-8" }).mockReturnValue(JSON.stringify(settingsFileContent));

It has been almost a week since I used the library in my project but is started throwing errors today. I've searched about it but only found some records about gulp.

Here is my task in vscode. When I run it, it gives me error below. Never fails when I comment out the only line of code that I use jest-when. Seemed like a version issue after I read the discussions about gulp but I am not sure. Any help is appreciated.

{
	"type": "node",
	"request": "launch",
	"name": "Launch jest",
	"program": "${workspaceFolder}/node_modules/.bin/jest",
        "windows": {
                "program": "${workspaceFolder}/node_modules/jest/bin/jest",
         },
	"args": ["--detectOpenHandles", "--watch"],
	"outputCapture": "std",
	"autoAttachChildProcesses": true,
	"outFiles": ["${workspaceFolder}/out/**/*.js"],
        "preLaunchTask": "build"
}
 RUNS  src/__tests__/app.test.ts
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe[24464]: c:\ws\src\node_contextify.cc:1035: Assertion `args[0]->IsString()' failed.
 1: 00007FF7003C3E0F napi_wrap+108911
 2: 00007FF700367E16 v8::base::CPU::has_sse+61910
 3: 00007FF700368191 v8::base::CPU::has_sse+62801
 4: 00007FF70037297A node::OnFatalError+40330
 5: 00007FF700BEDDCF v8::internal::Builtins::builtin_handle+321711       
 6: 00007FF700BED364 v8::internal::Builtins::builtin_handle+319044       
 7: 00007FF700BED657 v8::internal::Builtins::builtin_handle+319799       
 8: 00007FF700BED4A3 v8::internal::Builtins::builtin_handle+319363       
 9: 00007FF700CC9C8D v8::internal::SetupIsolateDelegate::SetupHeap+465453
10: 00007FF700C62092 v8::internal::SetupIsolateDelegate::SetupHeap+40498 
11: 00007FF700C62092 v8::internal::SetupIsolateDelegate::SetupHeap+40498 
12: 00007FF700C62092 v8::internal::SetupIsolateDelegate::SetupHeap+40498 
13: 00007FF700C62092 v8::internal::SetupIsolateDelegate::SetupHeap+40498 
14: 00007FF700C62092 v8::internal::SetupIsolateDelegate::SetupHeap+40498 
15: 00007FF700C62092 v8::internal::SetupIsolateDelegate::SetupHeap+40498 
16: 00007FF700C62092 v8::internal::SetupIsolateDelegate::SetupHeap+40498
17: 00007FF700C62092 v8::internal::SetupIsolateDelegate::SetupHeap+40498
18: 00007FF700C62092 v8::internal::SetupIsolateDelegate::SetupHeap+40498
19: 00007FF700C62092 v8::internal::SetupIsolateDelegate::SetupHeap+40498
20: 00007FF700C62092 v8::internal::SetupIsolateDelegate::SetupHeap+40498
21: 00007FF700C62092 v8::internal::SetupIsolateDelegate::SetupHeap+40498
22: 00007FF700C62092 v8::internal::SetupIsolateDelegate::SetupHeap+40498
23: 00007FF700C62092 v8::internal::SetupIsolateDelegate::SetupHeap+40498
24: 00007FF700C62092 v8::internal::SetupIsolateDelegate::SetupHeap+40498
25: 00007FF700C62092 v8::internal::SetupIsolateDelegate::SetupHeap+40498
26: 00007FF700C62092 v8::internal::SetupIsolateDelegate::SetupHeap+40498
27: 00007FF700C62092 v8::internal::SetupIsolateDelegate::SetupHeap+40498
28: 00007FF700C62092 v8::internal::SetupIsolateDelegate::SetupHeap+40498
29: 00007FF700C62092 v8::internal::SetupIsolateDelegate::SetupHeap+40498
30: 00007FF700C62092 v8::internal::SetupIsolateDelegate::SetupHeap+40498
31: 00007FF700C62092 v8::internal::SetupIsolateDelegate::SetupHeap+40498
32: 00007FF700C62092 v8::internal::SetupIsolateDelegate::SetupHeap+40498
33: 00007FF700C62092 v8::internal::SetupIsolateDelegate::SetupHeap+40498
34: 00007FF700C62092 v8::internal::SetupIsolateDelegate::SetupHeap+40498
35: 00007FF700C62092 v8::internal::SetupIsolateDelegate::SetupHeap+40498
36: 00007FF700C62092 v8::internal::SetupIsolateDelegate::SetupHeap+40498
37: 00007FF700C8F2C0 v8::internal::SetupIsolateDelegate::SetupHeap+225376
38: 00007FF700D0BE1E v8::internal::SetupIsolateDelegate::SetupHeap+736190
39: 00007FF700C8233D v8::internal::SetupIsolateDelegate::SetupHeap+172253
40: 00007FF700C5FC3C v8::internal::SetupIsolateDelegate::SetupHeap+31196
41: 00007FF700B2FB7F v8::internal::Execution::CallWasm+1839
42: 00007FF700B2FC8B v8::internal::Execution::CallWasm+2107
43: 00007FF700B306CA v8::internal::Execution::TryCall+378
44: 00007FF700B10CE5 v8::internal::MicrotaskQueue::RunMicrotasks+501
45: 00007FF700B10A40 v8::internal::MicrotaskQueue::PerformCheckpoint+32
46: 00007FF700BEDDCF v8::internal::Builtins::builtin_handle+321711
47: 00007FF700BED364 v8::internal::Builtins::builtin_handle+319044
48: 00007FF700BED657 v8::internal::Builtins::builtin_handle+319799
49: 00007FF700BED4A3 v8::internal::Builtins::builtin_handle+319363
50: 00007FF700CC9C8D v8::internal::SetupIsolateDelegate::SetupHeap+465453
51: 00007FF700C62092 v8::internal::SetupIsolateDelegate::SetupHeap+40498
52: 00007FF700C5FD4E v8::internal::SetupIsolateDelegate::SetupHeap+31470
53: 00007FF700C5F93C v8::internal::SetupIsolateDelegate::SetupHeap+30428
54: 00007FF700B2FAC1 v8::internal::Execution::CallWasm+1649
55: 00007FF700B2F32F v8::internal::Execution::Call+191
56: 00007FF700C1AEA7 v8::Function::Call+615
57: 00007FF7003F0C04 node::CallbackScope::~CallbackScope+868
58: 00007FF7003F0F7B node::CallbackScope::~CallbackScope+1755
59: 00007FF7003E8B74 v8::internal::compiler::Operator::EffectOutputCount+228
60: 00007FF700294F1F v8::internal::Isolate::isolate_root_bias+35119
61: 00007FF70040FFBE uv_process_kill+302
62: 00007FF700420CE9 uv_loop_init+1337
63: 00007FF700420E5A uv_run+202
64: 00007FF700322CD5 v8::internal::OrderedHashTable<v8::internal::OrderedHashSet,1>::NumberOfBucketsOffset+9365
65: 00007FF700396F37 node::Start+311
66: 00007FF7001F677C RC4_options+339580
67: 00007FF7011B874C v8::internal::compiler::RepresentationChanger::Uint32OverflowOperatorFor+152316
68: 00007FFE61057034 BaseThreadInitThunk+20
69: 00007FFE611A2651 RtlUserThreadStart+33

mockReturnValue doesn't work when returning a function

When configured to return a function, mockReturnValue calls that function and returns its return value, rather than returning the function itself. This is different to the behaviour of mockReturnValue on a plain jest.fn().

const returnValue = () => 'hello';

const mock1 = jest.fn();
mock1.mockReturnValue(returnValue);
expect(mock1('hi')).toBe(returnValue);

const mock2 = jest.fn();
when(mock2).calledWith('hi').mockReturnValue(returnValue);
expect(mock2('hi')).toBe(returnValue);

The first assertion succeeds but the second fails:

    expect(received).toBe(expected) // Object.is equality

    Expected: [Function returnValue]
    Received: "hello"

    Difference:

      Comparing two different types of values. Expected function but received string.

The problem is here:

return typeof returnValue === 'function' ? returnValue(...args) : returnValue

I think the simplest solution is to wrap the returnValue in a function here:

jest-when/src/when.js

Lines 86 to 87 in 25f0093

mockReturnValue: returnValue => _mockReturnValue(matchers, expectCall)(returnValue),
mockReturnValueOnce: returnValue => _mockReturnValue(matchers, expectCall, true)(returnValue),

support given syntax in addition to when

I like to follow the test pattern of given, when, then. This pattern makes using a syntax using when unintuitive in the given block (which is where this library would be used).

I have created aliases for the supported functionality in a fork, which look like this:

given(..).calledWith(..).returns             === when(..).calledWith(..).mockReturnValue
given(..).calledWith(..).onceReturns         === when(..).calledWith(..).mockReturnValueOnce
given(..).calledWith(..).resolvesTo          === when(..).calledWith(..).mockResolvedValue
given(..).calledWith(..).onceResolvesTo      === when(..).calledWith(..).mockResolvedValueOnce
given(..).calledWith(..).rejectsWith         === when(..).calledWith(..).mockRejectedValue
given(..).calledWith(..).onceRejectsWith     === when(..).calledWith(..).mockRejectedValueOnce
given(..).calledWith(..).isImplementedAs     === when(..).calledWith(..).mockImplementation
given(..).calledWith(..).onceIsImplementedAs === when(..).calledWith(..).mockImplementationOnce

This works with expectCalledWith too, of course.

The exports WhenMock, verifyAllWhenMocksCalled and resetAllWhenMocks are aliased to GivenMock, verifyAllGivenMocksCalled and resetAllGivenMocks respectively.

It would also "fix" the linguistic problems #24 mentions by allowing given(..).returns(..).

In my implementation the two syntaxes can be combined in any way, which allows for calls like given(..).calledWith(..).mockReturnValue(..). However, it should be relatively simply to disallow this, and I'd be happy to do so.

Is this something you'd be interested in supporting?

Allow usage without `calledWith` or `expectCalledWith`

When setting up mocks without any argument expectations, I get the following message:

Unintended use: Only use default value in combination with .calledWith(..), or use standard mocking without jest-when.

However, I would really rather have a single syntax for mock setups across the whole solution.

I understand that it does not play well linguistically with when, but perhaps a more neutral alias can be exposed, like setupMock, which would not produce this warning.

In fact, I am trying to migrate from a homemade solution where the function is named just that: setupMock.

How to mock with a callback?

I've got a mock which needs to call a callback. Currently this is not possible with your library.

As a workaround I've got this:

myMock.mockImplementationOnce((...args) => {
    expect(args).toEqual([
        'putObject',
        {
            Bucket: 'attachments',
            Key: 'some-guid',
            Expires: 900,
            ContentType: 'application/pdf',
        },
        expect.any(Function),
    ])

    const cb = _.last(args)

    cb(null, 'https://signed-url')
})

Deprioritize `expect.anything()` when applying `calledWith` matchers

I have a function where the first argument is an identifier and the second argument is an options object. Usually I don't care about the options object, so I frequently load my default data using expect.anything() for the second argument.

However for one test I need to load my data based on whether or not the options object contains some specific values. So I would like to be able to use expect.objectContaining to match against the options object without making the test too brittle by matching against the whole thing.

After doing some testing, it appears that jest-when doesn't currently support this, as expect.anything() is matched even though expect.objectContaining() would also match the call. I would prefer that jest-when would deprioritize expect.anything() over all other asymmetric matchers.

I'm running jest-when 3.5.2 and jest 27.5.1.

Here are the tests I wrote to nail down the issue:

it('supports expect.objectContaining()', async () => {
	const fn = jest.fn();

	when(fn).mockReturnValue(false);
	when(fn)
		.calledWith(
			'id',
			expect.objectContaining({
				k: 'v',
			})
		)
		.mockReturnValue(true);

	// this test passes
	expect(
		fn('id', {
			k: 'v',
		})
	).toBeTruthy();
});

it('deprioritizes expect.anything() against literal values', async () => {
	const fn = jest.fn();

	when(fn).calledWith('id', expect.anything()).mockReturnValue(false);
	when(fn)
		.calledWith('id', {
			k: 'v',
		})
		.mockReturnValue(true);

	// this test passes
	expect(
		fn('id', {
			k: 'v',
		})
	).toBeTruthy();
});

it('deprioritizes expect.anything() against other asymmetric matchers', async () => {
	const fn = jest.fn();

	when(fn).calledWith('id', expect.anything()).mockReturnValue(false);
	when(fn)
		.calledWith(
			'id',
			expect.objectContaining({
				k: 'v',
			})
		)
		.mockReturnValue(true);

	// this test fails
	expect(
		fn('id', {
			k: 'v',
		})
	).toBeTruthy();
});

Warnings because using deprecated lifecycles method in React 16.9.0

Hi, actually I'm receiving this warning when run my tests using react 16.9.0

console.log node_modules/jest-when/src/when.js:72
      Warning: componentWillReceiveProps has been renamed, and is not recommended for use. See https://fb.me/react-async-component-lifecycle-hooks for details.

      * Move data fetching code or side effects to componentDidUpdate.
      * If you're updating state whenever props change, refactor your code to use memoization techniques or move it to static getDerivedStateFromProps. Learn more at: https://fb.me/react-derived-state
      * Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.

any idea how to fix it?

Can't use calledWith null using 3.3.0

Seems like this usage of jest-when is broke on version 3.3.0, and work using 3.2.0

const fn = jest.fn();
when(fn).calledWith(null).mockReturnValue('yay!');
expect(fn(null)).toBe('yay!');

the test is failing and i get this in the logs

TypeError: Cannot read property '_isAllArgsFunctionMatcher' of null

versions -

"jest-when": "^3.3.0",
"jest": "26.6.3"

Thanks

jest-when doesn't reset with `.mockReset()`

I'm not able to reset a mock and clear our my previous settings. I have to declare a new jest.fn() in my beforeEach() to get my jest-whens to reset.

It would help to have mockReset() clear out the callMocks array.

Support for repeated calls with the same argument

It's a feature request. It would be nice to mock different return values for two (or more) different calls with the same arguments.

This could be a different method, e.g. calledWithOnce/expectCalledWithOnce.

I can submit a PR if you want

using symbols in matchers causes an error

when(mock).calledWith(Symbol.for(`dummy`));

results in "Cannot convert a Symbol value to a string" error at runtime.
The reason is that you try to log debug the matcher using string literals but Symbols can not work in them.
The issue occurs here -

logger.debug(` matcher: ${matcher}`)

Not working for mocked class method with callback

Hi all,
I recently started using this library but I'm not getting it to work with a mocked class method that receives a callback in one paramater.

Here's an example code (I'm using ts-jest here for the mocked()):

import { when } from 'jest-when';
import ExtensionStorage from '../src/extension-storage';

jest.mock('../src/extension-storage');

it('test', (done) => {
    const storage = new ExtensionStorage();
    when(mocked(storage.getSettings))
      .calledWith(expect.any(String), expect.anything)
      .mockImplementation((key, callback) => {
        callback('a');
      });

    storage.getSettings('', (val) => {
      expect(val).not.toBeNull(); // <---
      done();
    });
});

Where ExtensionStorage.getSettings is of type (key: string, callback: (settings: string | null) => void): void. In this case, the highlight line is never called.
However, if I use the default way without jest-when, it works:

const storage = new ExtensionStorage();
mocked(storage.getSettings).mockImplementation((key, callback) => callback('test'));
storage.getSettings('', (val) => {
   expect(val).not.toBeNull(); // <---
   done();
});

Any ideas? Thanks!

`.calledWithContaining(...)`

That would expect a Partial of each of the arguments and apply expect.objectContaining matcher internally to each of the passed arguments.

How it is useful

Imagine method A receiving an object { x: number, y: number, z: number } as a parameter and delegating to method B which wants an {x: number, y: number }. To avoid extra memory allocations (our app is sensitive to that), we pass the object as-is since it satisfies the reduced shape expected by method B.

However, .calledWith fails because there is an extra unexpected property.

Workaround:

  • We can currently emulate this by passing the expect.objectContaining matcher inside, but it has no type safety with Typescript.
  • Alternatively, we do an extra object allocation by destructuring the argument and reassembling only { x, y } for method B.

Build errors (node-gyp) stemming from bunyan/dtrace-provider deps

Is anyone else getting node-gyp errors related from the Bunyan dependency? I've read through various issues in the Bunyan and dtrace-provider repositories, but haven't found a concrete way around this that doesn't involve:

A) Installing python
B) Installing the windows essentials package
C) Manually editing the package-lock

Mainly just curious if anyone else is seeing this and if they have found a good workaround or if there is something we could change in the package.json to resolve the issue for everyone.

Unable to match when parameter itself is a mock?

I use jest-when quite a lot, and find it incredibly useful. However, I've struggled to get it to work when the calledWith parameter is itself a mock, like in the following scenario:

import { mock } from 'jest-mock-extended';
import { mocked } from 'ts-jest/utils';
import { when } from 'jest-when';
import { NodejsFunction } from '@aws-cdk/aws-lambda-nodejs';
import { LambdaDestination } from '@aws-cdk/aws-logs-destinations';

jest.mock('@aws-cdk/aws-logs-destinations');

test('jest-when matching on a mock', () => {
    const mockLambdaDestination = mock<LambdaDestination>();
    const mockLambda = mock<NodejsFunction>();
    when(mocked(LambdaDestination)).calledWith(mockLambda).mockReturnValue(mockLambdaDestination);

    const result = new LambdaDestination(mockLambda);

    expect(result).toEqual(mockLambdaDestination);
});

The above test fails:

Error: expect(received).toEqual(expected) // deep equality

Expected: undefined
Received: {"bind": [Function bind]}

which indicates to me that jest-when has not picked up that LambdaDestination was called with the argument mockLambda and hence isn't returning the value mockLambdaDestination.

However if I re-write the test to not use jest-when and instead check that LambdaDestination was called with the expected mock value, it passes:

import { mock } from 'jest-mock-extended';
import { mocked } from 'ts-jest/utils';
import { NodejsFunction } from '@aws-cdk/aws-lambda-nodejs';
import { LambdaDestination } from '@aws-cdk/aws-logs-destinations';

jest.mock('@aws-cdk/aws-logs-destinations');

test('jest matching on a mock without help from jest-when', () => {
    const mockLambdaDestination = mock<LambdaDestination>();
    const mockLambda = mock<NodejsFunction>();
    mocked(LambdaDestination).mockReturnValue(mockLambdaDestination);

    const result = new LambdaDestination(mockLambda);

    expect(result).toEqual(mockLambdaDestination);
    expect(LambdaDestination).toHaveBeenCalledWith(mockLambda);
});

So it appears that jest is able to work out that LambdaDestination was called with mockLambda, but that jest-when is not able to.

These examples use mock from jest-mock-extended and mocked from ts-jest. I could try to come up with examples that don't use these libraries if that would help.

Bug with classes `this` keyword

Take a look at this code:

import { when } from 'jest-when';

class MyName {
	reGetName( name: string ) {
		return name;
	}

	getName( name: string ) {
		return this.reGetName( name );
	}
}

it( 'test my name', () => {
	const component = new MyName();
	jest.spyOn( component, 'getName' );

	when( component.getName )
		.calledWith( 'mark' )
		.mockReturnValue( 'mark' );

	expect( component.getName( 'mark' ) ).toBe( 'mark' ); // Ok
	expect( component.getName( 'john' ) ).toBe( 'john' ); // Error
} );

Once run this test it gives this error:
TypeError: this.reGetName is not a function

The problem is jest-when change the default implementation of the function.

My temporary solution is reset the jest-when implementation by doing something like this:

it( 'test my name 2', () => {
	const component = new MyName();
	jest.spyOn( component, 'getName' );

	when( component.getName )
		.calledWith( 'mark' )
		.mockReturnValue( 'mark' )
		.defaultImplementation( MyName.prototype.getName.bind( component ) );

	expect( component.getName( 'john' ) ).toBe( 'john' ); // Ok
	expect( component.getName( 'mark' ) ).toBe( 'mark' ); // Ok
} );

To solve this issue jest-when should not change the function's implementation if it's not called with the added arguments.

Default wrongArgs implementation for README

Thanks for creating this!

I'm familiar with this technique in sinon, and I find that verifying arguments at the call site often results in better tests than verifying them after execution.

In trying to replicate the patterns I've used in sinon, it wasn't clear from the README how to write the default failing function that handles the wrong-args case.

I include my implementation below in hopes that you include it or something similar in your README:

// A default implementation that fails
const wrongArgs = (...args: any[]) => {
  throw new Error(`Wrong args: ${JSON.stringify(args, null, 2)}`);
};

when(fn)
  .mockImplementation(wrongArgs)
  .calledWith(correctArgs)
  .mockReturnValue(expectedValue);

Feature Request: create spy

Thanks for the amazing library! This is exactly what I have been looking for and I hope something like this gets added to the jest core codebase soon.

I have a lot of boilerplate code that I would like to reduce and I think with a small modification to this library I can make that happen. I often mock libraries that I use in my codebase to mock the return values from the library. For instance, in my code I might use an Azure sdk and write tests that will mock the return value of the SDK and test how my code behaves. It's possible to mock those classes easily with this library, but the code is a bit hard to read so cleaning it up would be nice.

current

when(jest.spyOn(MetricsAdvisorClient.prototype, 'listAnomalies'))
  .calledWith(1)
  .mockReturnValue(123);

when(jest.spyOn(MetricsAdvisorClient.prototype, 'listAnomalies'))
  .calledWith(2)
  .mockReturnValue(456);

Would you consider a PR for the when function to accept a second argument so I can do something like this:

when(MetricsAdvisorClient.prototype, 'listAnomalies')
  .calledWith(1)
  .mockReturnValue(123);

when(MetricsAdvisorClient.prototype, 'listAnomalies')
  .calledWith(2)
  .mockReturnValue(456);

Internally, the when function would call jest.spyOn when it sees 2 arguments and then return the when object as usual. I realize this example is trivial, but i sometimes have 3 different functions that im mocking and I think the code looks much cleaner with the second approach.

Another approach could be to export a new "when" function with a different name that calls jest.spyOn internally.

Let me know what you think.

Keep up the great work!

Keep default implementation when attaching to an existing mock

const test = jest.fn((yes: boolean): string => (yes ? 'pizza' : 'pasta'));
when(test).calledWith(true).mockReturnValueOnce('Luigi');

console.log(test(true));
console.log(test(false));

// Actual:
// Luigi
// undefined

// Expected
// Luigi
// pasta

Rationale:
I have a factory in one place of a system that returns a method that is already mocked in certain way. What I was specifically looking for is a convenient way of adding another condition to this mock in a different part of the system.

I understand that I can rewrite my original test declaration using jest-when, but the current behaviour of overriding existing implementations seems intrusive.

The syntax of when().calledWith() itself implies behaviour that only happens under specific conditions.

Cannot find module 'expect/build/jasmineUtils' from 'node_modules/jest-when/src/when.js'

Hi, after updating to the latest version our tests are failing on:

  โ— Test suite failed to run

    Cannot find module 'expect/build/jasmineUtils' from 'node_modules/jest-when/src/when.js'

    Require stack:
      node_modules/jest-when/src/when.js
      some.test.ts

      at Resolver.resolveModule (node_modules/jest-resolve/build/index.js:306:11)
      at Object.<anonymous> (node_modules/jest-when/src/when.js:2:15)

If I understand it correctly it is related to #84 and expect package.

In our project, we don't have any expect package directly in node_modules, only in subfolders.

$ npm ls expect
โ”œโ”€โ”ฌ [email protected]
โ”‚ โ””โ”€โ”ฌ @jest/[email protected]
โ”‚   โ”œโ”€โ”ฌ [email protected]
โ”‚   โ”‚ โ””โ”€โ”ฌ [email protected]
โ”‚   โ”‚   โ””โ”€โ”€ [email protected] 
โ”‚   โ”œโ”€โ”ฌ [email protected]
โ”‚   โ”‚ โ””โ”€โ”ฌ @jest/[email protected]
โ”‚   โ”‚   โ””โ”€โ”€ [email protected] 
โ”‚   โ””โ”€โ”ฌ [email protected]
โ”‚     โ””โ”€โ”€ [email protected] 
โ””โ”€โ”ฌ [email protected]
  โ””โ”€โ”ฌ [email protected]
    โ””โ”€โ”€ [email protected]

Any ideas on how to best fix it? I was not able to replicate this in a fresh project.

I guess one solution could be convincing npm to install one expect version directly to node_modules.

Support for function matchers breaks backward compatibility?

Hey @timkindberg, I noticed that v3.2.0 seems to break existing tests and I'm not sure if that's expected. Based on semver I'd expect not.

You can see an example in these check results for tjenkinson/gh-action-auto-merge-dependency-updates#113.
It may take a while until the results are loaded so I'm also pasting an example here:

run โ€บ when the event name is pull_request โ€บ with an allowed actor โ€บ errors if the content type is incorrect

    expect(received).rejects.toHaveProperty(path, value)

    Expected path: "message"

    - Expected value  -  1
    + Received value  + 11

    - Unexpected repo content response
    + octokit/plugin-throttling error:
    +         You must pass the onAbuseLimit and onRateLimit error handlers.
    +         See https://github.com/octokit/rest.js#throttling
    +
    +         const octokit = new Octokit({
    +           throttle: {
    +             onAbuseLimit: (retryAfter, options) => {/* ... */},
    +             onRateLimit: (retryAfter, options) => {/* ... */}
    +           }
    +         })
    +

      377 |               Promise.resolve({ data: { type: 'unknown' } })
      378 |             );
    > 379 |             await expect(run()).rejects.toHaveProperty(
          |                                         ^
      380 |               'message',
      381 |               'Unexpected repo content response'
      382 |             );

      at Object.args [as toHaveProperty] (../node_modules/expect/build/index.js:241:20)
      at run.test.ts:379:41
      at step (run.test.ts:52:23)
      at Object.next (run.test.ts:33:53)
      at run.test.ts:27:71
      at Object.<anonymous>.__awaiter (run.test.ts:23:12)
      at Object.<anonymous> (run.test.ts:375:57)

The related test code is https://github.com/tjenkinson/gh-action-auto-merge-dependency-updates/blob/56c26aed95cf78be3712376cb2d61b4eb041cfd3/src/run.test.ts#L347-L355.

When reverting 6190463 the tests are passing again. Do you have an idea what the issue might be? Thanks!

How to use mockResolvedValue with axios?

I'm still learning TypeScript, so maybe I'm just missing something, but how am I supposed to use mockResolvedValue with a mocked Axios object? See example snippet below:

jest.mock('axios')

const mockedAxios = axios as jest.Mocked<typeof axios>;

// doesn't work
when(mockedAxios.get)
    .calledWith('http://some-api')
    .mockResolvedValue('foo'); // complains that "Argument of type '"foo"' is not assignable to parameter of type 'never'.ts(2345)"

// this seems to work w/ the generic type hint, but is super ugly...
when<Promise<unknown>, any[]>(mockedAxios.get)
    .calledWith('http://some-api')
    .mockResolvedValue('foo');

I think it might have something to do with when(mockedAxios.get) resolving to WhenMock<unknown, [string, AxiosRequestConfig?]> (T being unknown specifically), but am kinda stumped.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.