Code Monkey home page Code Monkey logo

jest-mock-extended's People

Contributors

bbarry avatar brutyler avatar codeinabox avatar dependabot[bot] avatar dlech avatar effs avatar franky47 avatar hantsy avatar hnisiji avatar iisergey avatar jeremyloy avatar laurence-hudson-mindfoundry avatar marchaos avatar millsp avatar moltar avatar msftenhanceprovenance avatar nlkluth avatar regevbr avatar s-montigny-desautels avatar shinglyu avatar skovhus avatar sytten avatar timdavish avatar toilal avatar vdhpieter avatar vinh0604 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  avatar

jest-mock-extended's Issues

Matcher to match object by values instead of reference

First of all: thank you so much for this package. It's super helpful and makes testing in TS finally fun. ๐Ÿ™๐Ÿป

I had to test the following code:

class SubjectUnderTest
{
    private someService: ServiceA;

   constructor(someService: ServiceA) {
       this.someService = someService;
   }

    public someMethod(object args): void {
        this.someService.do({id: 'foo', ...args})
    }
}


// Test
describe('test subjextUnderTest', () => {
   it('test', async () => {
       const args = {foo: 'bar'};

       const mockServiceA = mock<ServiceA>();
       mockServiceA.do.calledWith({id: 'foo', ...args})
   });
});

The problem is that the both objects don't share the same reference (it seems if you pass in arguments to calledWith() they are matched by reference) and I had to write a custom matcher to match the object's properties.

const myMatcher: MatcherCreator<object> = (expectedValue) => new Matcher((actualValue) => {
    for (const key in expectedValue) {
        if (expectedValue[key] !== actualValue[key]) {
            return false;
        }
    }
    return true;
});

What do you think if we supply such a matcher (maybe add support for nested objects) with this package? I assume this is a quite generic matcher that can be of use for many people using this package.

An improved version could be a general equals matcher that compares values with === objects by iterating over them and comparing the values with ===:

import { Matcher, MatcherCreator } from 'jest-mock-extended';

export const equals: MatcherCreator<any> = expectedValue => new Matcher((actualValue) => {
    return compareValue(expectedValue, actualValue);
});

function compareValue(expectedValue: any, actualValue: any): boolean 
{
    if (typeof actualValue !== typeof expectedValue) {
        return false;
    }

    if ('object' === typeof actualValue) {
        return compareObject(expectedValue, actualValue); 
    }

    return expectedValue === actualValue;
}

function compareObject(expectedValue: object, actualValue: object): boolean
{
    for (const key in expectedValue) {
        if (false === compareValue(expectedValue[key], actualValue[key])) {
            return false;
        }
    }

    return true;
}

mockReset doesn't work well with calledWith

When performing mockReset, the jest.fn() method is being reset which is great, but the inner state of the calledWith scope is maintained, thus the jest.fn() is not called again with mockImplementation and the call stack just gets piled up

Test hangs when async method returns a mock

Hello there, I've found a problem that is keeping me from using this very helpful package.

I have a use case very similar to the structure of this example code, where my test subject receives an async factory as dependency which is called inside of it to do stuff:

it('should work', async () => {
  interface Engine {
    start: () => Promise<void>;
  }

  const makeCar = async ({ makeEngine }) => {
    const engine = await makeEngine(); // code hangs here
    return {
      turnOn: async () => {
        await engine.start();
        return true;
      },
    };
  };

  const engineMock = mock<Engine>();
  const car = await makeCar({ makeEngine: async () => engineMock });
  await car.turnOn();
  expect(engineMock.start).toHaveBeenCalled();
});

The problem here is that the code hangs on await makeEngine() for some reason.

If I change the factory to not be async like this const car = await makeCar({ makeEngine: () => engineMock }); it will work perfectly.
Also if I change engineMock for a simple mock object like { start: jest.fn() } it will also work, which leads me to think that the problem is in this library.

Do you have any idea on what could be causing this issue?

Thanks!

calledWith return value redefinition dont work

Hi!

I use jest-mock-extended v1.0.10 + jest v24.9.0
Failing to change return value of calledWith for the same argument. Here is a minimal example:

import { mockDeep } from 'jest-mock-extended';

interface A {
  f: (s: string) => string;
}

const m = mockDeep<A>();
const value = 'value';
m.f.calledWith(value).mockReturnValue('result 1');
m.f.calledWith(value).mockReturnValue('result 2');

test('', () => {
  expect(m.f(value)).toBe('result 2');
});

Test fails, m.f(value) returns 'result 1'.
Is this a bug?

mockClear() is not removing calledWith() from mocks

Hi!

If I use mockClear() in combination with calledWith() it is still using the previous mocks:

import { mock, mockClear } from 'jest-mock-extended';

class Implementation {
  public doSomething(arg: string): string {
    return arg;
  }
}

describe('mockClear should clear calledWith', () => {
  let mockedClass = mock<Implementation>();
  afterEach(() => {
    mockClear(mockedClass);
  });

  it('should do sth', () => {
    mockedClass.doSomething.calledWith('hello').mockReturnValue('firstMock');
    expect(mockedClass.doSomething('hello')).toEqual('firstMock');
  });

  it('should do sth2', () => {
    mockedClass.doSomething.calledWith('hello').mockReturnValue('secondMock');
    expect(mockedClass.doSomething('hello')).toEqual('secondMock');
    // fails with:
    // Error: expect(received).toEqual(expected) // deep equality

    // Expected: "secondMock"
    // Received: "firstMock"
  });
});

Workaround for now is to re-create the mock instead of calling mockClear()

Private properties prevent casting

This is a complex problem. I am a mocking a class from the Prisma library that looks like

export declare class PrismaClient<T extends PrismaClientOptions = {}, U = keyof T extends 'log' ? T['log'] extends Array<LogLevel | LogDefinition> ? GetEvents<T['log']> : never : never> {
  private fetcher;
  private readonly dmmf;
  private connectionPromise?;
  private disconnectionPromise?;
  private readonly engineConfig;
  private readonly measurePerformance;
  private engine: Engine;
  private errorFormat: ErrorFormat;
  get event(): EventDelegate;
}

I store an instance of this class in a context type:

export type Context = {
  prisma: PrismaClient;
};

For my tests, I created a mock type for the context:

export type MockContext = {
  prisma: MockProxy<PrismaClient>;
};

When I want to pass this mock context to the function to test, it is unable to cast the type to a Context because of the private properties:

Conversion of type 'MockContext' to type 'Context' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
  Types of property 'prisma' are incompatible.
    Type 'MockProxy<PrismaClient<{}, never>>' is missing the following properties from type 'PrismaClient<{}, never>': fetcher, dmmf, engineConfig, measurePerformance, and 3 more.

So for now I did a hack where I store a casted context in my mocked context:

export type MockContext = {
  prisma: MockProxy<PrismaClient>;
  ctx: Context;
};

export const createMockContext = (): MockContext => {
  const baseCtx = {
    prisma: mockDeep<PrismaClient>(),
  };

  const mockCtx = {
    ...baseCtx,
    ctx: baseCtx as Context,
  };

  return mockCtx;
};

But it would be great if I could just cast the mock context directly.
Thanks a lot!

Angular Services cannot be mocked in Angular TestBed

If I mock an Angular Injectable Service, I get the following as soon as I include it in the module providers list:

TypeError: function is not iterable (cannot read property Symbol(Symbol.iterator))
    at new Set (<anonymous>)

Pseudo code (edited for simplicity)

const issueServiceMock = mock<IssueService>();
TestBed.configureTestingModule({
  imports: [ReactiveFormsModule, RouterTestingModule],
  declarations: [
    IssueDashboardContainerComponent
  ],
  providers: [
    {provide: IssueService, useValue: issueServiceMock},
  ]
});
fixture = TestBed.createComponent(IssueDashboardContainerComponent);  // CRASHES HERE

Empty array in mock

This test fails with "RangeError: Invalid array length"

interface Test {
    arr: String[]
}

it('tests', () => {
    let m = mock<Test>({ arr: [] });

    expect(m.arr).toHaveLength(0);
})

deep mocks to deeply mock functions

Currently, when creating a deep mock, there is no way to control the mocks of return values of first level mocked functions.

Essentially I want to be able to do:

interface A {
  y: () => Promise<string>;
}

interface B {
  x: () => Promise<A>;
}

const mocked = mockDeep<B>();
mocked.x.y.mockResolvedValue(`str`);

Mock array inside an interface returns Proxy

Hi, I want to mock this interface:

export interface FileRequest {
    readonly folder: string;
    readonly params: any[];
}

I do something like this:

const mockFileRequest = mock<FileRequest>({
        _id: FileRequestHelper.generateObjectID(),
        folder: 'mock-folder',
        params: [
          {
            param1: {
              param11: 'value11'
            }
          },
          {
            param2: {
              param21: 'value21'
            }
          }
        ]
      });

And when I want to see its content, I realize that params property has the type Proxy.

Any solution?

Order of calling mock.calledWith() matters

Unless I'm missing something, which is quite possible. The order in which you set up mocks with calledWith matters.

A simple example:

describe('A simple example', () => {
  let mockHttpClient: MockProxy<HttpClient>;

  beforeEach(() => {
    mockHttpClient = mock<HttpClient>();
  });

  it('will return the most generic mock value if it\'s defined first', async () => {
    mockHttpClient.get.calledWith(any()).mockResolvedValue('first');
    mockHttpClient.get.calledWith(anyString()).mockResolvedValue('second');
    mockHttpClient.get.calledWith('bar').mockResolvedValue('third');


    await expect(mockHttpClient.get('foo')).resolves.toBe('second');
  });
});

in the example above the mock returns 'first'. In this example it isn't that big of a deal, you could just reorder them and put the more specific ones ontop and the mock works as expected.

However, the use case where I think it becomes problematic is if you want to define the generic mockResolvedValue in a beforeEach for all tests, and then define more specific mockResolvedValues with in a specific test, this behavior will cause an issue in that scenario.

Here's an example of the more problematic use case for reference

describe('A simple example', () => {
  let mockHttpClient: MockProxy<HttpClient>;

  beforeEach(() => {
    mockHttpClient = mock<HttpClient>();
    mockHttpClient.get.calledWith(any()).mockResolvedValue('first');
  });

  it('will return the most generic mock value if it\'s defined first', async () => {
    mockHttpClient.get.calledWith(anyString()).mockResolvedValue('second');
    mockHttpClient.get.calledWith('bar').mockResolvedValue('third');
    await expect(mockHttpClient.get('foo')).resolves.toBe('second');
  });
});

Any insight or suggestions is appreciated. Also, love this library. It's super useful.

Mocking boolean

class Test {
    value: number;
    flag: boolean;
}

it('tests', () => {
    var t = mock<Test>({value: 123, flag: false});

    expect(t.value).toBe(123);
    expect(t.flag).toBeFalsy();
});

Running the above test fails with:

expect(received).toBeFalsy()
Received: [Function mockConstructor]

Edit: Noticed that this is a duplicate of #30, for which a PR exists. Please merge it.

boolean field mock changes to function on access

After defining a mock for a class with values

const mock = mock<MyClass>({ b: false, s: 'someText' }); // option 1
...
const mock = mock<MyClass>(); // option 2
mock.b = false

and accessing it with mock.b the field changes to a function mockConstructor () ....
What's even more weird is that mock.s returns someText as expected

Mock as iterable object

Hello
I had problem with expect(mock).toEqual(mock), because in a method toEqual be call iterator for the mock and own mock return not correct data for an iterator. You can see more information in https://medium.com/front-end-weekly/thank-u-symbol-iterator-next-aef9f09ff78. I used expect(mock.property).toEqual(mock.property)

interface SomeObject {
  name: string;
}
it('should work', async () => {
  const mockObject= mock<SomeObject>();
  mockObject.name = 'mock';
  expect(mockObject.name ).toEqual(name ); // that work correct
  expect(mockObject).toEqual(mockObject); // Error
});

Example Error:

TypeError: Cannot read property 'next' of undefined

    at Object.test (src\Mock.spec.ts:271:37)
    at Object.asyncJestTest (node_modules\jest-jasmine2\build\jasmineAsyncInstall.js:102:37)
    at resolve (node_modules\jest-jasmine2\build\queueRunner.js:43:12)
    at new Promise (<anonymous>)
    at mapper (node_modules\jest-jasmine2\build\queueRunner.js:26:19)
    at promise.then (node_modules\jest-jasmine2\build\queueRunner.js:73:41)
    at process.internalTickCallback (internal/process/next_tick.js:77:7)

Problem mocking interface that has 'name' property.

Hi,
I use jest-mock-extended 1.0.13. Can not setup property 'name' of the mock. The following test

interface A {
  name: string;
}

interface B {
  a: A;
}

test('', () => {
  const bMock = mockDeep<B>();
  bMock.a.name = '';
});

ends up with

TypeError: Cannot assign to read only property 'name' of function 'function mockConstructor() {
    return fn.apply(this, arguments);
}'

Provide mock implementations

Instead of having to modify mock implementations manually, it might be nice to allow an argument as the first argument in mock<...>({ ... }) which defines mock implementations/values for the instance:

interface ResourcesApi {
    get(id: string): Promise<any>
}

interface Api {
    resources: ResourcesApi
}

const api = mock<Api>({
  resources: {
    get: true // equivalent to api.resources.get.mockReturnValue(true)
    // or get: () => true which is equivalent to api.resources.get.mockImplementation(() => true)
  }
})

// instead of ...
// 

Refer to #3 for the nested support.

Thoughts?

typescript 3.9.4 compilation issues

After upgrading to typescript 3.94 I started getting the following errors:

 error TS2590: Expression produces a union type that is too complex to represent.

The issue doesn't happen for ts 3.8

To reproduce, install the latest typeorm package and typescript 3.9.4 and run:

import { Connection } from 'typeorm';
import * as typeorm from 'typeorm';
import { mock } from 'jest-mock-extended';

const typeOrmMock = mock<typeof typeorm>();
const connectionMock = mockDeep<Connection>();
typeOrmMock.createConnection.mockResolvedValue(connectionMock); //  error TS2590: Expression produces a union type that is too complex to represent.

Bug: mocking Date with calling date.getHours() causes Error

I've got a bug:

interface d {
date: Date
}
let m = mock ({
date: new Date()
})

m.date.getHours() //leads to TypeError: this is not a Date object at Proxy.getHours ()

Reason:
Current get method of Proxy's handler loses its context:
return obj[property]

Solving:
Bind a context for the functions:
return obj[property].bind(obj)

As a more specific solving: bind context only for Date's function

Add generics to mockReturnValue and mockResolvedValue

It would be good to be able to override the return types via generic param to the mockReturnValue and mockResolvedValue.

The use case is that I am mocking a third party library (aws-sdk), which has a very complicated return type, and I don't actually care about all of the meta return values. I only need to mock the value that I care about in my application.

Thanks.

.then defined as a property on an object cannot be used for mock implementations

This breaks older APIs that might chain a .then() call, like the following example using jsforce:

Minimum test setup example:

const batchMock = mock<jsforce.Batch>();
batchMock.then.mockResolvedValue(123)
// TypeError: Cannot read property 'mockResolvedValue' of undefined

Batch source code with .then defined on Batch prototype: https://jsforce.github.io/jsforce/doc/api_bulk.js.html#line486

The reason is the following line:

if (property === 'then') {

`mockResolvedValue` Type Error

First, I'm using prisma as Type ORM client with apollo-server-express. My use case is context mock like below

context/contextMock.ts

import { MockProxy, mockDeep } from "jest-mock-extended";
import { Request, Response } from "express";

export type MockContext = {
  request: MockProxy<Request>;
  response: MockProxy<Response>;
  ...
}

export const createMockContext = (): MockContext => {
  return {
    request: mockDeep<Request>(),
    response: mockDeep<Response>(),
    ...
  }
}

myErrorTestCode.spec.ts

import { MockContext, Context, createMockContext } from "~/context/contextMock";
import { myRequest, myController } from "..";
import expressRequestMock from "express-request-mock";

let mockCtx: MockContext;
let ctx: Context;
let myController: MyController;

describe("myRequest", () => {
  beforeEach(() => {
    mockCtx = createMockContext();
    ctx = mockCtx as unknown as Context; // Needed until https://github.com/marchaos/jest-mock-extended/issues/25
    myController = new myRequest(ctx.prisma)
      .myController;
  });
  it("should return isExist is false when token is not exist", async () => {
    mockCtx.prisma.myToken.findFirst.mockResolvedValue(null); // <-- Type Error
    const resJson = {
      status: 400,
      errorCode: 10021,
      message: "Invalid token",
      schema,
      version,
    };
    const { res } = await expressRequestMock(myController);
    const data = JSON.parse(res._getData());
    expect(res.statusCode).toBe(400);
    expect(data).toEqual(resJson);
  });
}

It was fine [email protected]. after upgrate to [email protected] report type error not having mockResolvedValue

How can I change use case in version 2?

Thank you.

Mocking objects with non-function values

Hi! Is it possible to mock simple objects somehow based on interfaces where the value is not a function?

Instead

interface PartyProvider {
   getPartyType: () => string;
   getSongs: (type: string) => string[];
}

I'd like to mock

interface PartyProvider {
   getPartyType: string;
   getSongs: string[];
}

(and also being able to do that in nested form).

Cannot pass mock as parameter for toBeCalledWith

When I call toBeCalledWith passing another mock as parameter an error occurs.

Sample code:

expect(myMock.sampleMethod).toBeCalledWith(otherMock);

Error:

TypeError: Result of the Symbol.iterator method is not an object

Handle nested mocked values

As the title says, when there are nested callable values, I would expect those to be typed as mocked values too.

interface ResourcesApi {
    get(id: string): Promise<any>
}

interface Api {
    resources: ResourcesApi
}

const api = mock<Api>()

// The next line will get a type error because `get` isn't mocked.
api.resources.get.mockReturnValue(true)

Thoughts?

How to clear or reset all the mocked functions?

Firstly, thanks for creating this, it's brilliant.

Before each of my tests I want to clear out my mocks but I can't find an easy way to do this. I could go function by function but this is messy when mocking a large interface. I know I could also just re-instantiate the mocked interface but that feels wrong. I imagine it takes time compared to just doing a mockReset() or mockClear() on each function.

Ideally, I'd like this, or similar.

    const mockUserService: UserService = mock<UserService>();
    let userController: UserController;

    beforeEach(() => {
        mockUserService.mock.mockReset();
        userController = new UserController(mockUserService);
    });

Maintainer help?

@marchaos Do you need help with maintenance? If you setup CICD for npm publish, I would be willing to help merge the PR and release version.

ESM compabillity

Since 1.0.17 or 1.0.18 this package no longer works with jest in esm mode.

image

I think it's because of the new different typescript compilation.

it will be cool to have an equality matcher

Instead of creating a custom matcher, it will be cool to include one built in.
For example:

import { Matcher } from 'jest-mock-extended';
import { equals } from 'expect/build/jasmineUtils';

export const isEqual = <T>(expectedValue: T) =>
  new Matcher<T>((actualValue: T) => {
    return equals(actualValue, expectedValue);
  });

MockImplementations are mocked wihout using deepMock

Hi!

When passing a mock implementations to mock, every sub object get wrapped in a Proxy. For example,

class ObjectWithMap {
  map = new Map();
}

const test = mock({ objectWithMap: new ObjectWithMap() });
console.log(util.types.isProxy(test)); // -> true
console.log(util.types.isProxy(test.objectWithMap)); // -> true
console.log(util.types.isProxy(test.objectWithMap.map)); // -> true

Which I think is quite unexpected. I believe it should only happen when using the deepMock function.
Also, it break some built-in object (Map, Set, Date, etc) as seen in #59.

Is it the expected behavior?

strictmock functionality

Trying to figure out whether there a straightforward manner to assert failure on unexpected mock invocations. Using the latest code an unexpected invocation results in an undefined, which in the case of Promises bubbles it's way through the SUT.

I currently employ a workaround where I hang assert raising implementations after my other .calledWith (the calledWiths are evaluated in order of declaration, so the fall through has to be the last one), e.g.

const mockApi = mock<APIClass>();

// mockApi being provided to SUT
mockApi.get
            .calledWith(CORRECT_API, "/some-path", anyObject())
            .mockResolvedValue(response);

// hook to catch errant mockApi calls
mockApi.get
            .mockImplementation(strictMockFallThrough);
            
sut = new Sut(mockApi);
// this should only hit CORRECT_API
expect(sut.refresh()).toStrictEqual([item1, item2, item3]);

However this is suboptimal as firstly the strictmock semantic has to be implemented in multiple places throughout a test rather than once at mock creation. The second problem is that whilst Jest itself uses exceptions for signalling test failure, if mocked method returns promises this exception is turned into a Promise.reject rather than test assertion. Perhaps something like:

expect(mockApi.get).unexpectedly.toHaveBeenCalledTimes(0);

Google Mock offers strictmock adapters, shows the gist.

Inability to use mocks with rxjs

Hello,

Very nice library, which works well in a lot of cases, except..

Most of my code involves RxJS observables and I can't do something as simple as

const x = mock<T>();
await lastValueFrom(of(x));

It ends with a timeout due to the implementation of of in RxJS.

It seems to boil down to RxJS looking for a schedule property/method on the object passed to of(), and when that property is present RxJS goes down the "wrong" path thinking a scheduler was passed.

There is already a quick fix for promises in the proxy used by jest-mock-extended: https://github.com/marchaos/jest-mock-extended/blob/master/src/Mock.ts#L91

I don't know if it's feasible to add a similar condition for schedule, as it might be a legit property/method in code tested by current users...

Mocha

Would this work in mocha?

Using calledWith where a parameter in an object is a callback

I have the following code in my application

public get<T>(
      url: string,
      params: AxiosRequestConfig
  ): Promise<AxiosResponse<T>> {
  return this.axiosInstance.get<T>(url, params);
}

where params is something like

{
  baseURL: 'example.com',
  headers: {
    'X-Custom-Header': '...',      
  },
  transformResponse: (data) => {
     return JSON.parse(...callbackfunction(data));
  }

When I mock this using the following code

mockAxiosInstance
    .get
    .calledWith(
        'any',
        objectContainsKey('baseURL') &&
        objectContainsValue('example.com') &
        objectContainsKey('headers') &&
        objectContainsValue({'X-Session-Key'
        objectContainsKey('transformResponse
    )
    .mockReturnValue(new Promise(() => {}));

This works without any problems, however, as you can see I also have a callback function as an option. How would I mock that?

Thank you :) Your library helped me so far.

Unable to mock getter

Is it possible to mock getters?
I always get the error Cannot assign to 'xyz' because it is a read-only property

Change name of calledWith method

Hi,

I love this library and use it for all my tests. However, one thing has caught me and my colleagues out several times. It hinges around the calledWith matcher.

In the following code:

      mockServiceApi.updateService.calledWith(4, 2).mockResolvedValue(42);

We all continually mistake this to mean "expect this method to be called with parameters 4 and 2 and, if so, return a promise to 42".

We therefore continually think that this should fail with an error if the updateService method is called with some other parameters. This is because we are used to jest code where we say things like:

      expect(mockServiceApi.updateService).toHaveBeenCalledWith(4, 2);

which would throw an error if it wasn't called with those parameters.

I believe calledWith is actually saying "when this method is called with parameters 4 and 2 then return a promise to 42".

So, if it is called with some other parameters then it will not do the action of returning a promise to 42.

I think it would help if this was renamed to whenCalledWith. The code would then read:

      mockServiceApi.updateService.whenCalledWith(4, 2).mockResolvedValue(42);

This would make it explicit that its not an expectation that will throw. You could just introduce a new matcher named whenCalledWith that just forwards on to calledWith to keep your library backwards compatible.

What do you think?

Yarn v2 support

I get the following error when trying to install jest-mock-extended when using Yarn v2

jest-mock-extended@npm:1.0.8 [f88a9] doesn't provide typescript@>=3.7.0 requested by ts-essentials@npm:4.0.0

Can you add typescript as a peerDependency? Here's the Yarn advice.

Date proxy in 2.0.4 breaks comparison

I have a test like this that is now breaking because obj.createdAt is a Proxy, not a Date after upgrading to 2.0.4. (excuse the indentation, i omitted some irrelevant context)

class MyModel extends Model {
  id!: string
  otherField!: string
  containerId!: string
  createdAt!: Date
  deletedAt?: Date

  findOne = jest.fn()
  findAll = jest.fn()
}

describe('Paginator', () => {
  const paginator = new Paginator()

  beforeEach(() => {
    jest.resetAllMocks()
  })

    it('when DESC returns less-than where clause', async () => {
      const obj = mock<MyModel>({ id: 'mem_123', createdAt: new Date('2021-05-21T16:12') })
      MyModel.findOne = jest.fn().mockReturnValueOnce(obj)

      const whereOptions = await paginator._getPaginationWhereOptions(
        MyModel,
        { otherField: 'banana' },
        { limit: 10, cursorObjectId: 'mem_123', cursorDirection: 'forwards' },
        'createdAt',
        'DESC',
      )

      expect(whereOptions).toStrictEqual({
        createdAt: {
          [Op.lt]: obj.createdAt,
        },
      })
  })
})

The failure reported is

FAIL ../../src/core/services/__tests__/Paginator.test.ts
  โ— Paginator โ€บ _getPaginationOptions โ€บ when DESC returns less-than where clause

    expect(received).toStrictEqual(expected) // deep equality

    Expected: {"createdAt": {Symbol(lt): "2021-05-21T16:12:00.000Z"}}
    Received: serializes to the same string

      66 |       )
      67 |
    > 68 |       expect(whereOptions).toStrictEqual({
         |                            ^
      69 |         createdAt: {
      70 |           [Op.lt]: obj.createdAt,
      71 |         },

      at Object.<anonymous> (../../src/core/services/__tests__/Paginator.test.ts:68:28)

Workaround: I can get this test to pass by declaring obj like

const obj = mock<MyModel>({ id: 'mem_123', createdAt: mock<Date>() })

but I don't love this, and other tests may require the date to be a specific value and be comparable to other dates.

Is this a bug? Is there a better way to write the expect() that is failing?

mocking promises?

so I was going to use a deep mock for this, but didn't find a way to do it, is there a better way? if not could there be a better way?

    const axios: MockProxy<AxiosInstance> = mock<AxiosInstance>();
    const response: MockProxy<AxiosResponse> = mock<AxiosResponse>();
    response.data = {
      result: user,
    };
    axios.get.mockResolvedValue(response);

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.