DEV Community

Cover image for Write an Integration test, not a Unit test
Alex Kondrashov
Alex Kondrashov

Posted on

Write an Integration test, not a Unit test

As a lazy software engineer I want to write code only when necessary. If I happen to write code I want to utilise it as much as possible. If this sounds like you, then let’s look at how Integration tests can allow your code to be more efficient.

Too Long To Read

Write both, Integration and Unit tests, when you have enough time or it’s a critical piece of your system. Write Integration tests first when time is off the essence.

More…

Integration test — is a type of software testing in which the different units, modules or components of a software application are tested as a combined entity.

Unit test proves correct work of one unit only. Whereas an Integration test proves work of more than one unit.

System Under Test

Why is it important to understand what is System Under Test? It will help us define the efficient test.

System under test (SUT) — system that is being tested for correct operation.

It’s normal that Integration test covers wider SUT than a Unit test. Let’s consider the following test:

[Fact]
public async void IntegrationTest()
{
    var client = new HttpClient();
    var model = new Model();

    var result = await client.PostAsync(_url, new StringContent(JsonConvert.SerializeObject(model)));
    var expectedModel = JsonConvert.DeserializeObject<Model>(await result.Content.ReadAsStringAsync());

    var response = await client.GetAsync($"{_url}/{expectedModel.Id}");
    var actualModel = JsonConvert.DeserializeObject<Model>(await result.Content.ReadAsStringAsync());

    Assert.Equal(expectedModel.Id, actualModel.Id);
    Assert.Equal(expectedModel.Name, actualModel.Name);
}
Enter fullscreen mode Exit fullscreen mode

The SUT for the test above is the whole journey of a request in a web service (Controller, Service, Repository and Database). Depending on our assertions we can catch a potential issue in all layers of this web service.

Image description

Here is how a Unit test might look for Controller in a web service:

[Fact]
public async void UnitTest()
{
    var serviceMock = new Mock<IService>();
    serviceMock.Setup(p => p.MyServiceMethod()).Returns(true);
    var controller = new MyController(serviceMock);

    var model = new Model();
    var expectedModel = controller.MyControllerMethod(model);

    Assert.Equal(1, expectedModel.Id);
    Assert.Equal("Expected Name", expectedModel.Name);
}
Enter fullscreen mode Exit fullscreen mode

The SUT for the test above is one layer (Controller):

Image description

As we can see, Integration tests cover wider SUT than Unit tests with similar amount of code.

Bottom Line

Writing a proper Integration is challenging as it requires initial set up. Yet it pays off with time. Invest your time at the beginning and get a sense of stability about your code later.

Here is how you can ensure you’re writing an Integration test:

🗄️ Use a test instance of database, a test tenant in an external dependency etc.

🖥️ Use test servers instead of mocking and stabbing.

🐳 Use Docker for easier dependency management.

Resources

  1. My example of an Integration test. Refer to the README for instructions of how to run it.
  2. I've discovered a nice Diagram editor: Mermaid digram editor.

Top comments (15)

Collapse
 
ecyrbe profile image
ecyrbe • Edited

First of all,
even if i do not agree with the message of your article, it's a well written one and explains clearly how to test WEB APIs as a whole , so thanks you.

Now on the part a disagree with, here is my point of view.
Integration tests are costly, e2e tests are even more.

I would always recommend unit testing first unless it's not possible (design issues that force to do integration tests).
When developping a feature, you can do unit tests within your workflow (TDD). Which allow for early bug fixing and early refactoring.

It's impossible to do the same with integration testing since you need to have developped a huge part of your system before even considering it.

And even then, how can you be confident where is the issue when you have integration errors?

You have no unit tests, the problems you'll face could be in one part of a pretty Big system.. And it may even not be an integration issue... You'll have a hard time debugging and fixing.
Integration tests are there to check integration issues, not check your code has no bugs. Unit tests are here for that.

Thanks for reading.

Collapse
 
kondrashov profile image
Alex Kondrashov

Thanks for the comment and for reading my post.

I do agree with you that Integration testing requires more time setting up than Unit testing. I also do agree that with Integration Tests you will spend more time debugging and locating the exact place in the code that errored out. Yet, the Pros will outweigh the Cons.

Unit testing might give you confidence in one layer, say a Service layer. However when you run the Controller, Service and Repository together - there is no proof that it's all working.

You might re-use a lot of your setup across different Integration tests. Once you spend time setting it up for one test, you will most likely save time setting it up for other tests.

Obviously it might happen that Unit testing is better for a given project than Integration test, but my post was largely targeted to general CRUD web services where you would get the most benefits with Integration testing.

Loved reading through your comment!

Collapse
 
carlovo profile image
Carlo van Overbeek

I guess the truth is somewhere in the middle. TDD can be done on integration tests as well. Also, on unit tests you usually have to mock out stuff, but what are you going to mock if you haven't yet decided on the implementation? In the end, the test design choice of a good developer beats a static rule of what tests to write first.

That being said, the best developer experience I ever had was on a project where I had to extend integration tests and then build functionality for it. Some unit test were there as well, but had only been build in the start of the project. Newer parts were not unit tested. When the bigger picture of the project became clear the shift was made from unit test to integration test driven design. I think I'm going to advocate this flow as well if I'm at a new project inception.

Collapse
 
kondrashov profile image
Alex Kondrashov

I had similar experience where I would TDD with integration tests. Worked well

Collapse
 
varian97 profile image
Varian Caesar

When the deadline approaching, I agree with you that integration tests come first. But personally I think this is come with one major cost, either your integration test will become very detailed (because it tries to test things that should be tested in unit test) or your integration test not cover much use cases (because you skip the unit tests that should test various things, like edge case for that function/class/whatever).

At the end of the day, the main important thing is to also include time to create tests (both unit and integration tests) into your project deadline estimation. Nice article by the way

Collapse
 
kondrashov profile image
Alex Kondrashov

Thanks for your feedback.

Regarding very detailed integration test: I came across this problem before. To solve it I've added a new Integration test per each use case. This helped me to keep my tests not too detailed but cover as much functionality as possible.

Collapse
 
billie34 profile image
Billie • Edited

First, we run the unit tests. Unit tests must be present for integration tests to run. Testers validate the integration success after developers have suika game tested all components of an application.

Collapse
 
baba123 profile image
Alibaba

Basketball Wordle is a slam dunk in the world of word games! If you're a basketball enthusiast or just someone who loves a good word challenge, this game is a winning combination.

Collapse
 
jamesalan profile image
James

Alex Kondrashov's article on choosing integration tests over unit tests in software development is thought-provoking. His argument that integration tests can be more beneficial, especially for CRUD web services, offers a new perspective on testing. It's interesting how he points out the broader coverage and practicality of integration tests. This article definitely provides food for thought for developers in reevaluating their testing strategies.

Regards
James from Pokemon Games

Collapse
 
tecno21 profile image
Sumaid S

Convertidor MP3 has proven to be an essential ally in my digital music journey. It flawlessly converts audio files with a user-friendly interface and speedy performance.

Collapse
 
baba123 profile image
Alibaba

Candy Riddles is an absolute delight for word game enthusiasts with a sweet tooth! This game adds a delectable twist to the classic word puzzle genre, making it both fun and challenging.

Collapse
 
baba123 profile image
Alibaba

BTS Heardle is not just a game; it's an auditory adventure for music lovers! This unique twist on word games is an absolute delight for fans of BTS and music enthusiasts alike.

Collapse
 
baba123 profile image
Alibaba

Worgle is an absolute brain-teaser and a true gem among word games! The game's clean and intuitive design makes it a joy to play, and the word challenges keep you engaged for hours on end.

Collapse
 
chris79 profile image
Christine Barber

This is very interesting content! I have thoroughly enjoy reading your points and have come to the conclusion word that you are right about many of them. You are great! Word Hurdle dordle

Collapse
 
james13 profile image
James J

Convertidor MP3 is a game-changer! This tool makes converting audio files a breeze. The user-friendly interface and swift conversion process have saved me so much time.

Some comments may only be visible to logged-in visitors. Sign in to view all comments.