Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test using a TypeMoq.It.is() with passed by reference predicate fails #121

Closed
jeep87c opened this issue Feb 1, 2019 · 2 comments
Closed

Comments

@jeep87c
Copy link

jeep87c commented Feb 1, 2019

I'm writing some custom matchers using the TypeMpq.It.is() method referencing a const object in the passed predicate. The test fails on the === check. See the following code:

import * as TypeMoq from 'typemoq';

class FooBar {
  public static foo(someMethod: SomeMethod, bar: Bar): void {
    someMethod({ bar: bar });
  }
}

type SomeMethod = (payload: any) => void;

class Bar {
  public _name: string;

  constructor(name: string) {
    this._name = name;
  }
}

describe('FooBar example', () => {
  const BAR = new Bar('Bob');
  const someMethodMock: TypeMoq.IMock<SomeMethod> = TypeMoq.Mock.ofType<SomeMethod>();

  it('test', () => {
    FooBar.foo(someMethodMock.object, BAR);

    someMethodMock.verify(
      someMethod => someMethod(TypeMoq.It.is((payload: { bar: Bar }) => {
        return payload.bar === BAR;
      })), TypeMoq.Times.once());
  });
});

As JS/TS pass by reference objects, I was expecting this test to pass. Unfortunately, the === fails. Objects are obviously equals but, at this point, they are not the same instance (memory addresses are different) thus failing the test.

Is this an issue, an implementation details/specificity or an incomprehension of myself around JS/TS with arrow functions and pass by reference?

Here's the test output results:

1 failing

  1) FooBar example
       test:
     MockException - invocation count verification failed (expected invocation of Function(It.is(payload => {
      return payload.bar === BAR;
    })) exactly 1 times, invoked 0 times
 Configured setups:
 Function(It.is(payload => {
      return payload.bar === BAR;
    }))

 Performed invocations:
 Function({"bar":{"_name":"Bob"}})

Thank you

@jeep87c
Copy link
Author

jeep87c commented Feb 1, 2019

Still playing with this, if I change my verify for this:

someMethodMock.verify(someMethod => someMethod({bar: BAR}), TypeMoq.Times.once());

it pass...

I clearly don't understand how this works.

@jeep87c
Copy link
Author

jeep87c commented Feb 1, 2019

Ok I think I understand why the first case (without the setup but with the TypeMoq.It.is call in the verify) was failing.

In your implementation, I'm guessing you are saving an invocation to a method by keeping a deep copy of parameters. Doing otherwise would result in weird issues since you have no guaranty that code under test will not modify these objects/arrays (there's no issue for primitives).

So if I understand correctly, the right way to verify in my test scenario is to use the 3rd case/example (verify without TypeMoq.It.is). There's no way to do a === verify on objects/arrays due to language limitation (objects/arrays are passed by reference forcing your library to do a deep copy on passed parameters while recording invocations).

Sorry for disturbing. Looks like I finally figure it out myself 😂

@jeep87c jeep87c closed this as completed Feb 1, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant