NagRock / ts-mockito

Mocking library for TypeScript
MIT License
977 stars 93 forks source link

Can't return just one item on .thenResolve() #168

Open volkz opened 5 years ago

volkz commented 5 years ago

Hi,

I'm trying to mock a promise call than return just one object.

image

This "getOne" and "Create" method return a promise of mocked repository passed type (IUser)

image

After hours of research, i found the problem... On method "thenResolve" at MethodStubSetter.d.ts it's expected to receive an array of items, not just one...

image

I expect to return just one IUser item so i can't resolve the function with an instance of that, because that function always expect an array... how can i solve it without change my models? it's not logic to return an array of "getOne" or create function...

Thanks

mmarchois commented 5 years ago

@volkz Have you found a solution? I have the same problem https://github.com/NagRock/ts-mockito/issues/172

mmarchois commented 4 years ago

Found a solution by using deepEqual. It works perfectly !

volkz commented 4 years ago

@mmarchois how does you that with deepEqual? resolving the promise? can you give me a example please?

mmarchois commented 4 years ago

Here is one of my tests

    customerRepository = mock(CustomerRepository);
    isCustomerAlreadyExist = mock(IsCustomerAlreadyExist);
    createdCustomer = mock(Customer);
// ...
when(isCustomerAlreadyExist.isSatisfiedBy('Customer')).thenResolve(
      false
    );
    when(createdCustomer.getId()).thenReturn(
      '2d5fb4da-12c2-11ea-8d71-362b9e155667'
    );
    when(createdCustomer.getName()).thenReturn('Customer');
    when(
      customerRepository.save(deepEqual(new Customer('Customer')))
    ).thenResolve(instance(createdCustomer));

    expect(await handler.execute(command)).toMatchObject(
      new CustomerView('2d5fb4da-12c2-11ea-8d71-362b9e155667', 'Customer')
    );

    verify(isCustomerAlreadyExist.isSatisfiedBy('Customer')).once();
    verify(
      customerRepository.save(deepEqual(new Customer('Customer')))
    ).once();
    verify(createdCustomer.getId()).once();
    verify(createdCustomer.getName()).once();
volkz commented 4 years ago

Here is one of my tests

    customerRepository = mock(CustomerRepository);
    isCustomerAlreadyExist = mock(IsCustomerAlreadyExist);
    createdCustomer = mock(Customer);
// ...
when(isCustomerAlreadyExist.isSatisfiedBy('Customer')).thenResolve(
      false
    );
    when(createdCustomer.getId()).thenReturn(
      '2d5fb4da-12c2-11ea-8d71-362b9e155667'
    );
    when(createdCustomer.getName()).thenReturn('Customer');
    when(
      customerRepository.save(deepEqual(new Customer('Customer')))
    ).thenResolve(instance(createdCustomer));

    expect(await handler.execute(command)).toMatchObject(
      new CustomerView('2d5fb4da-12c2-11ea-8d71-362b9e155667', 'Customer')
    );

    verify(isCustomerAlreadyExist.isSatisfiedBy('Customer')).once();
    verify(
      customerRepository.save(deepEqual(new Customer('Customer')))
    ).once();
    verify(createdCustomer.getId()).once();
    verify(createdCustomer.getName()).once();

@mmarchois I tried with this code but it return me a null response (from instance) , i don't know what's the error but thanks for the advice, i will search for some solution... thanks!

`exampleUser = mock(User); when(exampleUser.name).thenReturn("Jane"); when(exampleUser.email).thenReturn("jdoefalse@test.com"); when(exampleUser.password).thenReturn("123456"); when(exampleUser.configuration).thenReturn({ gps: false, time: false, lims: { authenticated: false, host: "", user: "", password: "" } });

when(mockedRepository.getOne(deepEqual(exampleUser))).thenResolve( instance(exampleUser) );`

xenoterracide commented 4 years ago

hmm... I'm not sure it's the same issue, but... I'm gonna comment here, and maybe open a new issue.

given this

beforeAll(() => {
  testContainer.register(Beans.CEC_LOCATION, {
    useFactory: (c) => {
      const contextMock = mock<ContentfulEntryContext<ContentfulLocationFields>>();
      const entryMock = mock<Entry<ContentfulLocationFields>>();
      when(entryMock.fields).thenReturn({
        id: '42',
        name: 'Deep Mind',
      });
      when(contextMock.get()).thenResolve(instance(entryMock));
      const location = (id: string) => {
        return instance(contextMock);
      };
      location('42').get().then((v) => console.log(v));
      return location;
    },
  });
});

my instance never resolves, however if I do this, it does

beforeAll(() => {
  testContainer.register(Beans.CEC_LOCATION, {
    useFactory: (c) => {
      const contextMock = mock<ContentfulEntryContext<ContentfulLocationFields>>();
      when(contextMock.get()).thenResolve(new class implements Entry<ContentfulLocationFields> {
        fields: ContentfulLocationFields | any = { name: 'Deep Mind', id: '42' };
        sys: Sys | any = undefined;

        toPlainObject(): object | any {
          return undefined;
        }

        update(): Promise<Entry<ContentfulLocationFields>> | any {
          return undefined;
        }
      });
      const location = (id: string) => {
        return instance(contextMock);
      };
      const promise = location('42').get();
      return location;
    },
  });
});

at this moment, it feels like the problem is thenResolve doesn't like returning the proxy instance for some reason.

xenoterracide commented 4 years ago

mine is issue #163