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

Cascading Mocks for different matches of the 'base' mock #153

Closed
Milraun opened this Issue Mar 16, 2015 · 4 comments

Comments

2 participants
@Milraun

Milraun commented Mar 16, 2015

I have the following code. Already the first assert fails because jmockit can't differentiate the cascading mocks due to parameters in the base mock. It would be a big help if this would be possible.

  private interface CascadingMock {
    String getString();
  }
  private interface BaseMock {
    CascadingMock getCascadingMock(String name);
  }

  @Test
  public void cascadingMockTest(@Mocked BaseMock baseMock) {
    new Expectations() {{
      baseMock.getCascadingMock("John").getString(); returns("John1", "John2");
      baseMock.getCascadingMock("Hugo").getString(); returns("Hugo1", "Hugo2");
    }};

    assertEquals("John1", baseMock.getCascadingMock("John").getString());
    assertEquals("Hugo1", baseMock.getCascadingMock("Hugo").getString());
    assertEquals("John2", baseMock.getCascadingMock("John").getString());
    assertEquals("Hugo2", baseMock.getCascadingMock("Hugo").getString());
  }
@Milraun

This comment has been minimized.

Show comment
Hide comment
@Milraun

Milraun Mar 17, 2015

I've changed my test to use two instances of baseMock. Unfortunately with the same result. The 'generated' cascading mock does not differentiate instances.

 @Test
  public void cascadingMockTest(@Injectable BaseMock baseMock1, @Injectable BaseMock baseMock2) {
    new Expectations() {{
      baseMock1.getCascadingMock("John").getString(); returns("John1", "John2");
      baseMock2.getCascadingMock("Hugo").getString(); returns("Hugo1", "Hugo2");
    }};

    assertEquals("John1", baseMock1.getCascadingMock("John").getString());
    assertEquals("Hugo1", baseMock2.getCascadingMock("Hugo").getString());
    assertEquals("John2", baseMock1.getCascadingMock("John").getString());
    assertEquals("Hugo2", baseMock2.getCascadingMock("Hugo").getString());
  }

Milraun commented Mar 17, 2015

I've changed my test to use two instances of baseMock. Unfortunately with the same result. The 'generated' cascading mock does not differentiate instances.

 @Test
  public void cascadingMockTest(@Injectable BaseMock baseMock1, @Injectable BaseMock baseMock2) {
    new Expectations() {{
      baseMock1.getCascadingMock("John").getString(); returns("John1", "John2");
      baseMock2.getCascadingMock("Hugo").getString(); returns("Hugo1", "Hugo2");
    }};

    assertEquals("John1", baseMock1.getCascadingMock("John").getString());
    assertEquals("Hugo1", baseMock2.getCascadingMock("Hugo").getString());
    assertEquals("John2", baseMock1.getCascadingMock("John").getString());
    assertEquals("Hugo2", baseMock2.getCascadingMock("Hugo").getString());
  }

@rliesenfeld rliesenfeld self-assigned this Mar 17, 2015

@rliesenfeld

This comment has been minimized.

Show comment
Hide comment
@rliesenfeld

rliesenfeld Mar 17, 2015

Member

I will see if it's possible (ie, without breaking existing tests) to create new cascaded instances for recorded expectations, instead of reusing existing ones.

For now, one has to declare separate mocks for the intermediate objects and explicitly record them. For example:

    @Test
    public void cascadingMockTest(
        @Mocked BaseMock baseMock, 
        @Mocked CascadingMock john, @Mocked CascadingMock hugo
    ) {
        new Expectations() {{
            baseMock.getCascadingMock("John"); result = john;
            john.getString(); returns("John1", "John2");

            baseMock.getCascadingMock("Hugo"); result = hugo;
            hugo.getString(); returns("Hugo1", "Hugo2");
        }};

        assertEquals("John1", baseMock.getCascadingMock("John").getString());
        assertEquals("Hugo1", baseMock.getCascadingMock("Hugo").getString());
        assertEquals("John2", baseMock.getCascadingMock("John").getString());
        assertEquals("Hugo2", baseMock.getCascadingMock("Hugo").getString());
    }
Member

rliesenfeld commented Mar 17, 2015

I will see if it's possible (ie, without breaking existing tests) to create new cascaded instances for recorded expectations, instead of reusing existing ones.

For now, one has to declare separate mocks for the intermediate objects and explicitly record them. For example:

    @Test
    public void cascadingMockTest(
        @Mocked BaseMock baseMock, 
        @Mocked CascadingMock john, @Mocked CascadingMock hugo
    ) {
        new Expectations() {{
            baseMock.getCascadingMock("John"); result = john;
            john.getString(); returns("John1", "John2");

            baseMock.getCascadingMock("Hugo"); result = hugo;
            hugo.getString(); returns("Hugo1", "Hugo2");
        }};

        assertEquals("John1", baseMock.getCascadingMock("John").getString());
        assertEquals("Hugo1", baseMock.getCascadingMock("Hugo").getString());
        assertEquals("John2", baseMock.getCascadingMock("John").getString());
        assertEquals("Hugo2", baseMock.getCascadingMock("Hugo").getString());
    }
@Milraun

This comment has been minimized.

Show comment
Hide comment
@Milraun

Milraun Mar 18, 2015

Hello Rogerio,

thx for your answer. I'm aware that it works with separate mocks for the intermediate objects, bit IMO are a quite unique feature of jmockit to write concise tests.

If there is a way I would be quite happy :-)

Jürgen

Milraun commented Mar 18, 2015

Hello Rogerio,

thx for your answer. I'm aware that it works with separate mocks for the intermediate objects, bit IMO are a quite unique feature of jmockit to write concise tests.

If there is a way I would be quite happy :-)

Jürgen

@rliesenfeld rliesenfeld added bug and removed enhancement labels Mar 22, 2015

@rliesenfeld

This comment has been minimized.

Show comment
Hide comment
@rliesenfeld

rliesenfeld Mar 22, 2015

Member

As it turns out, this is in fact a bug. It only happens when the CascadingMock type is an interface; when it's a class, a different cascaded instance is already obtained from every different call to a method in BaseMock.

Member

rliesenfeld commented Mar 22, 2015

As it turns out, this is in fact a bug. It only happens when the CascadingMock type is an interface; when it's a class, a different cascaded instance is already obtained from every different call to a method in BaseMock.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment