Integration tests vs Unit tests

Integration tests vs Unit tests

There are various types of testing which happens in the software development process. Unit testing, Integration testing, System testing etc.

Some use TDD, write the test cases first and then code and some write the test cases after code is done. Both the approaches have their advantage, though I am more favoured towards TDD as it ensures that you are writing modular and testable code from the beginning.

If you have never used TDD, or you are against it then please read the articles listed at the bottom of this article. Also, please post your opinions on those articles itself to get proper answers to your questions :)

Mostly, you will find that there are Unit test cases and Integration test cases. Some people get confused about these and in fact I have met some people who have the opinion that because we write the integration tests, unit tests are not required.

Let's understand the difference between these two first.

Unit tests

  1. Should test only single unit
  2. Should be short and fast

As stated in the above points, Unit test is responsible for testing only single unit. It should never test the multiple layers or multiple classes. As it covers single unit it should be fast, as you are going to have lots of unit test cases.

Another point in unit tests is, you can assert the logic/data conversion or specific implementation that you use in your application. Important thing is to test the logic and not have test to just add the coverage.

E.g. let's say you have row mapper in which you are converting db values into some Enum values depending on some condition

public class ProfileRowMapper implements RowMapper<Profile> {

    @Override
    public Profile mapRow(ResultSet resultSet, int i) throws SQLException {
        Profile profile = new Profile();
        profile.setType(ProfileType.valueOf(resultSet.getString("type")));
        profile.setPicturePath(getPicturePath(resultSet));
        return profile;
    }
    
    private String getPicturePath(ResultSet resultSet) {
        String picPath = resultSet.getString("pic_path");
        return picPath != null ? picPath : DEFAULT_PATH;
    }

}

Now following test case is adding the coverage but actually not testing the logic in the above code.

@RunWith(MockitoJUnitRunner.class)
public class ProfileRowMapperTest {

    private final ProfileRowMapper profileRowMapper = new ProfileRowMapper();
    @Mock
    private ResultSet resultSet;

    @Test
    public void testProfileMapping() throws SQLException {
        profileRowMapper.mapRow(resultSet, 1);
        verify(resultSet).getString("type");
        verify(resultSet).getString("pic_path");
    }
}

Test cases like above should be avoided. Whereas following test case asserts the data conversion happening in the mapper. Note that this is one of the expected test cases. Set of various test cases should verify that conversion is working for all expected values.

@RunWith(MockitoJUnitRunner.class)
public class ProfileRowMapperTest {

    private final ProfileRowMapper profileRowMapper = new ProfileRowMapper();

    @Mock
    private ResultSet resultSet;

    @Test
    public void testProfileMapping() throws SQLException {
        given(resultSet.getString("type")).willReturn("2");
        given(resultSet.getString("pic_path")).willReturn("some-pic-path");


        Profile profile = profileRowMapper.mapRow(resultSet, 1);


        assertEquals(ProfileType.PREMIUM, profile.getType());
        assertEquals("some-pic-path", profile.getPicturePath());
    }
}

Integration tests

  1. Should test integration between various layers
  2. Should not be there to cover some part of a unit

It doesn't make sense to write an Integration test case for testing a unit. Now, you will say this is obvious but I have seen people writing integration test cases to cover small units. And then not writing Unit test cases as it is already covered in the integration test cases!

So the point is Integration test cases should test the integration between various units. Integration test cases will be slow by the nature, and that's why integration test cases should be testing the integration and not the units.

Example of this would an integration test which provides input to a controller, in turn which will cover the flow till the point where data is fetched from database.

Consider following example of an integration test case

    @Test
    void createNewProduct() throws Exception {

        mockMvc.perform(post("/products")
                .contentType(MediaType.APPLICATION_JSON)
                .content(copyToString(newProductJsonResource.getInputStream(), StandardCharsets.UTF_8))
        )
        .andExpect(status().isOk())
        .andExpect(jsonPath("$.id", isNonNull()));

    }

These are not the only differences between unit and integration test cases but I think these are good enough to start writing both, unit and integration test cases.

Reposted from - https://techsach.com/integration-tests-vs-unit-tests/

Why TDD?

  1. https://martinfowler.com/bliki/TestDrivenDevelopment.html
  2. https://itnext.io/why-tdd-will-change-your-developer-life-b0bf234e15ac
  3. https://medium.com/@sukorenomw/why-tdd-test-driven-development-a1bc983a2cc0
Dhananjayan Gopalan

Software Development Engineer at LivePerson | Java | Microservices | Spring Boot | Docker | Kubernetes | AWS | Great Passion for Technology

3 年

Concise and Clear

回复

要查看或添加评论,请登录

Sachin Gorade的更多文章

  • Common misunderstandings of Software Developers

    Common misunderstandings of Software Developers

    Software development is a complicated subject. There are many things we have to learn almost every day and it is…

    1 条评论
  • Why Interfaces are recommend by Spring?

    Why Interfaces are recommend by Spring?

    Spring framework has become the central part of every Java based micro-service application. Spring beans work with…

    4 条评论
  • What makes REST API really usable?

    What makes REST API really usable?

    REST APIs are the most critical part of every application today, be it a blog or an application which is running on…

    8 条评论
  • Micro-services and DRY (Don't repeat yourself)

    Micro-services and DRY (Don't repeat yourself)

    DRY is one of the basic principles of software which not only programmers but the DBA, technical writers and everyone…

  • Why features fail?

    Why features fail?

    Unclear requirements Each product company follows a different path for adding new features. Some follow…

    6 条评论
  • Add real value, don't be workaholic!

    Add real value, don't be workaholic!

    Friday night, 10 pm and keyboard typing sound can be heard on the floor. The one who is creating that noise in the…

社区洞察

其他会员也浏览了