Search code examples
junitparameterized

How to perform Parameterized Junit Test Cases


i am learning Parameterized Junit test cases, i am trying to get user by Id. while performing this i am getting error: "Java.lang.IllegelArgumentException: Wrong number of arguments." please tell me what is the wrong with this code.

   @RunWith(Parameterized.class)
public class UserTestCases {

@Mock
UserRepository userRepository;

@InjectMocks
private UserServiceImpl userService;

private User user;
private User expectedUser;

public UserTestCases(User user, User expectedUser) {
    super();
    this.user = user;
    this.expectedUser = expectedUser;
}

@Parameters
public static Collection input() {
    User u1=new User(1, "india", "shiva");
    User u2=new User(2, "india", "shiva");
    User u3=new User(3, "india", "shiva");


    return Arrays.asList(new Object[][] {{new User(1L, "india", "shiva"), u1}, {new User(2, "india", "shiva"), u2},{new User(3, "india", "shiva"), u3}});

}

@Test
public void getUserByIdtest() {

        when(userRepository.findOne(user.getId())).thenReturn(user);
        User result=userService.findById(user.getId());
        assertEquals(user.getCountry(), expectedUser.getCountry());
        assertEquals(user.getName(), expectedUser.getName());
}
}

Thanks in advance


Solution

  • If you are learning to use JUnit, maybe you can try the last version: JUnit5.

    This last version make it easier to compose external features such as mocking, generating test cases, loading Spring beans etc.

    Moreover, it as built-in support for parameterized methods (tests), whereas JUnit4 as only parameterized classes (test suites) and was needed JUnitParams and its Runner to support parameterized tests.

    Your test can be written like this in JUnit5:

    @ExtendWith(MockitoExtension.class)
    class UserTestCases {
    
        @Mock UserRepository userRepository;
        @InjectMocks UserServiceImpl userService;
    
        @ParameterizedTest
        @MethodSource("input")
        void getUserByIdtest(User user, User expectedUser) {
            when(userRepository.findOne(user.getId())).thenReturn(user);
            User result = userService.findById(user.getId());
            assertEquals(user.getCountry(), expectedUser.getCountry());
            assertEquals(user.getName(), expectedUser.getName());
        }
    
        static Stream<Arguments> input() {
            return Stream.of(
                // static method of Arguments
                arguments(
                    new User(1, "india", "shiva"),
                    new User(1L, "india", "shiva")),
                arguments(
                    new User(2, "india", "shiva"),
                    new User(2L, "india", "shiva")),
                arguments(
                    new User(3, "india", "shiva"),
                    new User(3L, "india", "shiva")),
            );
        }
    }
    

    However, this test is just about delegation from UserServiceImpl to UserRepository, so you do not need parameterized tests here.

    The only test that is needed if you want to check delegation (without mapping it seems) is something like:

    class UserTestCases {
        @Mock UserRepository userRepository;
        @InjectMocks UserServiceImpl userService;
    
        @Test
        void getUserByIdtest() {
            User user = mock(User.class);
            when(userRepository.findOne(any())).thenReturn(user);
    
            assertEquals(userService.findById(1L), user);
        }
    }
    

    Such a test uses JUnit5 and Mockito libraries. If you are using Maven, your POM can be something like:

    <properties>
        <junit-jupiter.version>5.3.1</junit-jupiter.version>
        <mockito.version>2.23.0</mockito.version>
        <surefire-plugin.version>2.22.1</surefire-plugin.version>
    </properties>
    
    <dependencies>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-params</artifactId>
            <version>${junit-jupiter.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>${junit-jupiter.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
            <version>${mockito.version}</version>
            <scope>test</test>
        </dependency>
    </dependencies>
    
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>${surefire-plugin.version}</version>
            </plugin>
        </plugins>
    </build>
    

    Hope this helps !