RonW
RonW

Reputation: 41

How to set a value injected by Spring in a unit test?

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

Answers (2)

Jonathan S. Fisher
Jonathan S. Fisher

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

Christoph Schulze
Christoph Schulze

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

Related Questions