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

JUnit 5 and Nested classes #189

Open
acarpe opened this issue Apr 30, 2020 · 1 comment
Open

JUnit 5 and Nested classes #189

acarpe opened this issue Apr 30, 2020 · 1 comment

Comments

@acarpe
Copy link

acarpe commented Apr 30, 2020

Suppose to have this code: a context declared on the enclosing class and one or more nested classes.
It now fails with a no Mockery found in test class

public class NestedJUnit5TestThatDoesNotSatisfyExpectations
{
  @RegisterExtension
  JUnit5Mockery context = new JUnit5Mockery();

  Runnable runnable = context.mock(Runnable.class);

  @Nested
  class NestedClass {
    @Test
    public void doesNotSatisfyExpectations() {
      context.checking(new Expectations() {{
        oneOf (runnable).run();
      }});

      // Return without satisfying the expectation for runnable.run()
    }
  }
}

I tried to make pass this new test

    @Test
    public void testTheJUnit5TestRunnerLooksForTheMockeryInUpperClassOfInnerClasses() {
        listener.runTestIn(NestedJUnit5TestThatDoesNotSatisfyExpectations.class);
        listener.assertTestFailedWith(AssertionError.class);
    }

And as first step I modified the AllDeclaredFields to look in the enclosing classes

public class AllDeclaredFields {
    public static List<Field> in(Class<?> clazz) {
        final ArrayList<Field> fields = new ArrayList<Field>();
        for (Class<?> c = clazz; c != Object.class; c = c.getSuperclass()) {
            fields.addAll(asList(c.getDeclaredFields()));
        }
        for (Class<?> c = clazz.getEnclosingClass(); c != null; c = c.getEnclosingClass()) {
            fields.addAll(asList(c.getDeclaredFields()));
        }
        return fields;
    }
}

but then inside the checkMockery, I don't know how to get the instance of the enclosing types (it has the this$0 field but it's not accessible) to check that the field is not null

if(mockeryField.get(context.getRequiredTestInstance()) == null) {
    throw new IllegalStateException("JUnit5Mockery field should not be null");
}

And I was stuck there.
The only workaround I found was to declare a field inside the nested class and initialize it with the outer field, like this:

package org.jmock.junit5.testdata.jmock.acceptance;

import org.jmock.Expectations;
import org.jmock.auto.Mock;
import org.jmock.junit5.JUnit5Mockery;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

public class NestedJUnit5TestThatDoesNotSatisfyExpectations
{
  @RegisterExtension
  JUnit5Mockery outerContext = new JUnit5Mockery();

  Runnable runnable = context.mock(Runnable.class);

  @Nested
  class NestedClass {
    JUnit5Mockery context = outerContext;

    @Test
    public void doesNotSatisfyExpectations() {
      context.checking(new Expectations() {{
        oneOf (runnable).run();
      }});

      // Return without satisfying the expectation for runnable.run()
    }
  }
}
@olibye
Copy link
Member

olibye commented May 1, 2020 via email

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

2 participants