5

I've written a JUnit test that uses Mockito and PowerMock to mock some classes. I'm trying to convert it a Cucumber test, but the static PowerMock features don't work.

Extracts of the two relevant Cucumber classes:

Runner

@RunWith(Cucumber.class)
public class JWTValidatorBDDTest {
}

Steps Class

public class JWTValidatorCukeTest {
String tokenValue;
JWTValidator jwtValidator;
MockHttpServletRequest mockRequest;

@Before
public void before() throws IOException {
    this.mockRequest = new MockHttpServletRequest();
    PowerMockito.mockStatic(JWTAuthConnectionManager.class);
    BDDMockito.given(JWTAuthConnectionManager.postToken(anyString(), anyString(), anyString())).willReturn(200);
    Mockito.doReturn(200).when(JWTAuthConnectionManager.postToken(anyString(), anyString(), anyString()));
}

@Given("^a JWT token with the value (.*)")
public void a_JWT_token_with_the_value_(String token) {
    this.jwtValidator = new JWTValidator("https://test.7uj67hgfh.com/openam", "Authorization", "Bearer");
    this.tokenValue = token;
}

Whilst this code works within the JUnit test, it fails here - it enters the JWTAuthConnectionManager.postToken() method that should be mocked and then fails by executing code within there. I've tried adding the lines:

@RunWith(PowerMockRunner.class)
@PrepareForTest(JWTAuthConnectionManager.class)

to both of the above classes (although of course I can't use RunWith in the Runner class as it already has one RunWith annotation), but this doesn't change anything.

How do I get PowerMock to work within Cucumber?

Ben Watson
  • 5,357
  • 4
  • 42
  • 65
  • A bit outdated question but it might be related: https://stackoverflow.com/questions/55877324/breakpoints-are-not-triggered-while-debugging-gradle-cucumber-in-vscode – Pavel Sapehin Apr 19 '22 at 05:34

2 Answers2

1

Seems like it is possible now with @PowerMockRunnerDelegate annotation. I use @RunWith(PowerMockRunner.class) and @PowerMockRunnerDelegate(Cucumber.class) and it's working. Taken an advise from here: https://medium.com/@WZNote/how-to-make-spock-and-powermock-work-together-a1889e9c5692

Since version 1.6.0 PowerMock has support for delegating the test execution to another JUnit runner without using a JUnit Rule. This leaves the actual test-execution to another runner of your choice. For example tests can delegate to “SpringJUnit4ClassRunner”, “Parameterized” or the “Enclosed” runner.

There are also options of using @Rule: PowerMockRule rule = new PowerMockRule(); instead of @RunWith(PowerMockRunner.class) (so Runner can be something else) - but the comment by Stefan Birkner suggests that Cucumber runner should support rules to use this and I am not sure if it does (now).

Hope it helps someone.

Tatiana Goretskaya
  • 536
  • 10
  • 25
0

You can't use the PowerMockRunner because a test can only have one runner (in your case Cucumber). But AFAIK you can use the PowerMockRule instead of the PowerMockRunner.

Stefan Birkner
  • 24,059
  • 12
  • 57
  • 72
  • I've added "@Rule\nPowerMockRule rule = new PowerMockRule();" into both classes (also adding "@PrepareForTest" into both) with no change to the output. – Ben Watson Dec 01 '15 at 18:10
  • 2
    Sorry, my fault. The Cucumber runner doesn't support rules. – Stefan Birkner Dec 01 '15 at 21:50
  • Could you try `@ClassRule PowerMockRule rule = new PowerMockRule();`. It looks like The Cucumber runner is supporting ClassRules. – Stefan Birkner Dec 01 '15 at 22:31
  • `org.junit.internal.runners.rules.ValidationError: The @ClassRule 'rule' must implement TestRule` and `org.junit.internal.runnes.rules.ValidationError: The @ClassRule 'rule' must be static.` I've been looking at how `@ClassRule` works but I can't find a solution. – Ben Watson Dec 02 '15 at 08:34
  • :-( Looks like somebody has to build rule support for Cucumber: https://github.com/cucumber/cucumber-jvm/issues/894 – Stefan Birkner Dec 02 '15 at 08:53