-1

While implementing a unit test using JMockit with a @Capturing annotation and a Verification block for the "captured" variable I have 2 outcomes:

  1. IntelliJ: I can run and debug successfully, validating that the verification behaves correctly.

  2. Executing same test code with command line (cmd) using mvn test throws 'Missing invocation'.

It seems @Capturing behaves like @Mocked if using the cmd. As it is the exact behavior if I change the @Capturing to a @Mocked.

What would be the cause of this?

Settings:
IntelliJ: 2017.3.4
Java 8
JMockit 1.35

Thomas Fritsch
  • 9,639
  • 33
  • 37
  • 49
Beyonder
  • 21
  • 1
  • 5
  • Could you show an example test which fails from Maven but not from IntelliJ? And what version of Maven and the Surefire plugin are you using? – Rogério Mar 17 '18 at 14:55
  • Hi Rogério, snippet shown below: – Beyonder Mar 17 '18 at 16:05
  • Hi Rogerio, due to internal policy I can only share a minimal part regarding the error provided in cmd line: Missing 1 invocation to: manager#execute(any String, any String, any CalculateConfig, any java.util.Map) – Beyonder Mar 17 '18 at 19:41
  • maven version:3.5.2;surefire:2.20.1 – Beyonder Mar 17 '18 at 19:43
  • What I would need is a *complete* example test which reproduces the problem; doesn't need to be your real-world code. The code you provided has lots of unnecessary details, and none of the *code under test* is shown. Also, it should be added to the question, not in an answer. – Rogério Mar 18 '18 at 17:57

2 Answers2

0

Reference:

@Test
public void test(final @Mocked ProfileMgr profileMgr,
                                             final @Capturing Manager manager) throws Exception {


    final String id = “1234”;
    Final String modelId = “567”;
    final Map<String, String> effectiveProps = ImmutableMap.of("test.key", "test.value",
                                                               "ppp.key", "ppp.value"
    );

    final Optional<String> option = Optional.of("123");
    new Expectations() {{
        profileMgr.mergedProperties(
                id,IMPL_1,
                (Map<String, String>) any,
                option
        );
        result = effectiveProps;
    }};

    this.mainManager
            .run(
                    id,
                    modelId,
                    new JobRequestWrapper<>(config, IMPL_1, option);
            );

    new Verifications() {{
        final Map<String, String> params;
        manager.execute(
                anyString,
                anyString,
                (CalculationConfig) any,
                params = withCapture()
        );
        times = 1;
        assertThat(params)
                .withFailMessage("params must have content.")
                .isNotNull()
                .isNotEmpty();
        assertThat(params)
                .withFailMessage("params must have same injected entry.")
                .isEqualTo(effectiveProps);
    }};
}
Meo
  • 12,020
  • 7
  • 45
  • 52
Beyonder
  • 21
  • 1
  • 5
-1

In general, these kind of issues are usually due to maven running multiple tests in a single execution of the jvm. When you run a single unit test in IntelliJ, the test is well isolated, but when running with maven, any change of global variables in one test might have unexpected effects on the execution of other tests.

This is why one should avoid mutating (and even using) static variables in unit tests, use @DirtiesContext if you have spring-enabled tests that change your context, etc.

I don't have enough concrete information to pinpoint the exact problem in your case, but I would recommend that you start looking for something that would potentially change the behaviour of other tests. It's also possible to run multiple test classes at once with IntelliJ, doing this might be closer to how maven runs the tests.

Tobb
  • 11,850
  • 6
  • 52
  • 77
  • This is not correct. Both Maven Surefire and IntelliJ start a new JVM instance for the test run, executing all tests in that instance by default. – Rogério Mar 17 '18 at 14:57
  • Hi Tobb, thanks for your comment. That was my first guest, some mutating state but that symptom would appear when running the Class multiple times i think, not only the method. But this happens in the 1st run. – Beyonder Mar 17 '18 at 16:08
  • @Rogério The tests in a maven execution share the same jvm, and thus any static variable is shared between test classes and methods. I dont see that your comment in any way contradict my answer. – Tobb Mar 17 '18 at 18:23
  • So does test execution from any Java IDE, IntelliJ included. Besides, this has nothing to do with the problem described in the question, which happens with a single test. – Rogério Mar 18 '18 at 17:49
  • Yes, but typically in IntelliJ, one would run a single test class at a time. Which is also why I recommend trying to run multiple test classes in IntelliJ, to see if it behaves somewhat closer to how maven does it. From what I can tell the OP does not clearly state the number of tests in his project, so if you are not some kind of psychic you can't rule out that there are other tests affecting the one in question in the maven build (which is, as stated, often the problem when tests run fine in IntelliJ, but not with maven.) – Tobb Mar 18 '18 at 19:28
  • And now we have moved the post from "this is not correct", to "this does not answer the question". Make up your mind. – Tobb Mar 18 '18 at 19:29
  • Your answer is *both* incorrect and irrelevant to the question. And that "typical" IntelliJ usage is your personal opinion; I run a single test just as often as I run a whole test class, or a group of them. But it doesn't matter, since in all such cases the same JVM instance is used. – Rogério Mar 25 '18 at 16:35
  • Well, I have not stated anything but it being a single JVM instance (it's not the instance in different test runs though.) I stand by my answer, differences between test results when running a test in maven and when running them in an IDE is often due to tests modifying the context for other tests (changing global variables). When running tests with maven, one usually runs more tests in the same JVM instance than when running them in IntelliJ. Which is what you claim is wrong, while at the same time stating the exact same thing. I guess I'll have to let that be your problem. – Tobb Mar 25 '18 at 20:02