Reputation: 453
I must implement an Unit Test for MyUtility.class
in my Java application. However, It has a dependency on MyConfig.class
(It fetches configuration properties from application.yml
file).
class MyUtility {
MyConfig myConfig;
@Autowired
public MyUtility(MyConfig myConfig) {
this.myConfig = myConfig;
}
public String methodA() {
... // use myConfig.getValue() to perform some operation
methodB(); // call methodB()
...
}
public String methodB() { ... }
}
@Component
@ConfigurationProperties(prefix = "test")
class MyConfig {
String value; // to map test.value from application.yml
}
Using JUnit5, I'm trying to test the functionality methodA
. But, I don't need to test methodB
. Hence, I'm mocking the response of methodB
.
class ApplicationTests {
@Mock
MyConfig myConfig;
@Mock
MyUtility myUtility;
...
@Test
public void testMethodA() {
Mockito.when(myUtility.methodB()).thenReturn("someValue");
...
}
}
Since I've to mock MyUtility
, I'm also having to mock MyConfig
since it's a dependency (else myConfig
shows up as null
). But I don't want to mock MyConfig
. I want methodA
to use the value that is present in the application.yml
file rather than mocking it.
Is it possible to inject the MyConfig
from the application context into MyUtility
mock ?
Upvotes: 0
Views: 2823
Reputation: 4259
If I could autowire MyConfig into the mocked MyUtility, the code would work fine.
As long as you use the SpringExtension
and setup your configuration/context correctly you can do that. Instead of mocking MyConfig
add the autowired config to your testclass and pass that one to your creation of the MyUtility
class.
The reason I am mocking that specific method is because that method (methodB) is making a network call and returning a response back to methodA. I don't care about the network call.
The problem is that you currently mock the class (and not only the method). As @PaulBenn
already mentioned you want to use @Spy
instead of @Mock
.
A methodcall on a spy uses the real implementation as long as you have not defined different behaviour for it. A spy is normally created on a pre-existing instance of the object so all dependencies should be setup normally.
class ApplicationTests {
@Mock
MyConfig myConfig;
@Test
public void testMethodA() {
...
MyUtility spy = Mockito.spy(new MyUtility(myConfig));
Mockito.when(spy.methodB()).thenReturn("someValue");
spy.methodA();
...
}
}
Upvotes: 1