Reputation: 41
I am writing a Unit Test for the following class that is managed by Spring:
@Component
public class MyClass {
@Value("${urlValue}")
private String urlPath;
private MyUrl url = new MyUrl(urlPath);
public class MyUrl {
MyUrl(String url) {
if (url == null) {
throw new NullPointerException();
}
}
}
}
I'm trying to set urlValue
in the simplest way for my test. I tried the following:
public class MyClassTest {
private MyClass mc;
@Before
public void setUp() {
mc = new MyClass();
ReflectionTestUtils.setField(mc, "urlPath", "urlValue");
}
@Test
public void test() {
}
}
However the setting by reflection fails because it comes too late (new MyUrl()
is called before and throws an Exception). What would be the easiest way to set urlPath
, ideally (I assume) without changing the code, nor using a Spring context for the test ?
Upvotes: 2
Views: 2380
Reputation: 8886
https://github.com/exabrial/mockito-object-injection
We've created a JUnit Extension to solve this exact problem.
It's easy to use... see the README.md:
@TestInstance(Lifecycle.PER_CLASS)
@ExtendWith({ MockitoExtension.class, InjectMapExtension.class })
public class MyControllerTest {
Upvotes: 0
Reputation: 41
For unit testing a Spring component you need to make its members setable from outside. The easiest way to do this is by using constructor injection. Field injection requires you to run a @SpringBootTest
, which makes your unit test unreasonable slow as it creates a Spring context.
Have a look here: guide to unit test in spring boot
You could do it like this (didn't check for correctness):
@Component
public class MyClass {
private String urlPath;
private MyUrl url;
public MyClass(@Value("${urlValue}") String urlPath) {
this.urlPath = urlPath;
this.url = new MyUrl(urlPath)
}
public class MyUrl {
MyUrl(String url) {
if (url == null) {
throw new NullPointerException();
}
}
}
}
Upvotes: 1