Home > Software engineering >  How to write JUnit test for switch case?
How to write JUnit test for switch case?

Time:11-10

For example, method switchCase(). How do I write test code for it? I can just create 3 different tests just with different values for each test, respective to the switch case value, but I want to try a more efficient way of doing this.

    @InjectMocks
    private RepoFactory repoFactory;
    public void switchCase() {
            ConsentApplication consentApplication = repoFactory.getConsentApplicationRepo()
.findOne(consentApplicationVo.getId());

        switch (CrestApiServiceNameEnum.getByCode(serviceNameEnum.getCode())) {
            case CUST_DATA:
                newCrestApiTrack.setRepRefNo(null);
                httpHeaders.add("API-KEY", custDataApiKey);
                break;
            case CREDIT_PARAM:
                httpHeaders.add("API-KEY", creditParamApiKey);
                break;
            case CONFIRM_MUL_ENT:
                httpHeaders.add("API-KEY", multiEntitiApiKey);
                break;
            default:
                LOGGER.info("Unexpected value: "   CrestApiServiceNameEnum.getByCode(serviceNameEnum.getCode()));
        }
    }

What I tried was, using @RunWith(JUnitParamsRunner.class), @ValueSource and @ParameterizedTest. However, this always produces NullPointerException at the first when and java.lang.Exception: Method testSwitchCase_SUCCESS should have no parameters. Can help me on this?


   @ParameterizedTest
   @ValueSource(strings = {"value1", "value2"})
   void testSwitchCase_SUCCESS(String s) {

      //have something

             when(repoFactory.getConsentApplicationRepo().findOne(anyString()))
                .thenReturn(consentApplication);

   }

CodePudding user response:

Annotate your test either with @Test or @ParameterizedTest but not both.

From the JUnit 5 documentation:

Parameterized tests make it possible to run a test multiple times with different arguments. They are declared just like regular @Test methods but use the @ParameterizedTest annotation instead.

Also the @RunWith annotation is from JUnit 4. When using JUnit 5 this annotation is unnecessary and should be removed.

Then, as Lesiak has commented: you should separate IO and logic. A method the receives the string to switch on as parameter and returns an object is much easier to test than a method that does everything: read data from the user, operates on it and produce some terminal output.


It seems that you have a mix of JUnit 4 and JUnit 5 annotations. That doesn't really work. If you want to use JUnit 5 then remove all uses of org.junit.Test and org.junit.runner.RunWith from your test class and replace them with org.junit.jupiter.api.Test and org.junit.jupiter.api.extension.ExtendWith.

CodePudding user response:

Fortunately, I found a solution, the class should be annotated with @RunWith(JUnitParamsRunner.class) and @ExtendWith(MockitoExtension.class) and the in setup, we should put initMocks(this);. However, this will only mock a non-static class.

    @Before
    public void setup() {
        initMocks(this);
        setupRepos();
        setupLoginUser();
        setupUserLoginReturn();
        setupLoggerAppender();
    }
  • Related