I would like to implement an integration test with Spring Boot. I start with the spring-boot-starter-test
dependency, version 2.2.5.RELEASE
.
I have the following component:
@Component
public class MyMath {
public int add(int a, int b) {
return a + b;
}
}
The main program looks like this:
@SpringBootApplication
public class Main implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
}
@Autowired
private MyMath myMath;
@Override
public void run(String... args) throws Exception {
System.out.println(myMath.add(2, 3));
}
}
It works as expected - so far, so good. I would like to add a unit test:
@RunWith(SpringRunner.class)
@SpringBootTest
public class MyMathTest {
@Autowired
private MyMath myMath;
@Test
public void testSaveAndList() {
assertEquals(5, myMath.add(2, 3));
}
}
This also works, but according to the log it executes the whole program. I don't want to run the program itself, just the MyMath.add()
function. How can I do that?
I tried the following so far:
@RunWith(SpringJUnit4ClassRunner.class)
provided the same result.- Omitting
@SpringBootTest
resultsNoSuchBeanDefinitionException
. - Reformatting the code to have bean instead of component like below it works.
MyMath
without annotation:
public class MyMath {
public int add(int a, int b) {
return a + b;
}
}
Main
remains the same.
@Configuration
public class AppConfig {
@Bean
public MyMath getMyMath() {
return new MyMath();
}
}
And the test:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AppConfig.class)
public class MyMathTest {
@Autowired
private MyMath myMath;
@Test
public void testSaveAndList() {
assertEquals(5, myMath.add(2, 3));
}
}
So what I cannot do is to test a component without running the whole program. Could any help me? Thanks!
You do not need to refactor your code. Just keep the MyMath class as it is
@Component
public class MyMath {
public int add(int a, int b) {
return a + b;
}
}
Change your test class like this
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = MyMath.class)
public class MyMathTest {
@Autowired
private MyMath myMath;
@Test
public void testSaveAndList() {
assertEquals(5, myMath.add(2, 3));
}
}
This becomes a bit complex if your MyMath class has other dependencies autowired. Then you have to use mocks.