Reputation: 373
In my class TwitchService
I'm creating a private field twitchClient
using TwitchClientBuilder
. How can I approach testing method sendChatMessage()
which is using twitchClient
?
public class TwitchService {
public TwitchService(){
twitchClient = TwitchClientBuilder.builder().build();
}
public void sendChatMessage(String content) throws Exception {
if(content.isEmpty()){
throw new Exception("Cannot send empty message!");
}
twitchClient.getChat().sendMessage(content);
}
}
So far, I have tried mocking TwitchClientBuilder.builder()
and twitchCliendBuilder.build()
like this:
@RunWith(MockitoJUnitRunner.class)
public class TwitchServiceTest {
private TwitchService twitchService;
@Mock
private TwitchClientBuilder twitchClientBuilder;
@Test
public void sendChatMessage() throws Exception {
try (MockedStatic<TwitchClientBuilder> twitchClientBuilderMockedStatic = Mockito.mockStatic(TwitchClientBuilder.class)){
twitchClientBuilderMockedStatic.when(() -> TwitchClientBuilder.builder()).thenReturn(mock(TwitchClientBuilder.class));
when(twitchClientBuilder.build()).thenReturn(mock(TwitchClient.class));
twitchService = new TwitchService("x", "y");
twitchService.sendChatMessage("test message");
}
}
}
But I get NullPointerException
on twitchClient
in sendChatMessage()
Any ideas how to properly mock fields like this?
Upvotes: 0
Views: 80
Reputation: 2513
Use constructor dependency injection for TwitchClient
, instead of hard-coding it by calling builder.
Simply re-write your service, like so:
public class TwitchService {
private final TwitchClient twitchClient
public TwitchService(final TwitchClient twitchClient) {
this.twitchClient = twitchClient;
}
...
}
TwitchService
is now loosely-coupled with the implementation of TwitchClient
, which gives you ability to mock the client in the unit tests and use real-implementation (unit tested by itself) in real-code.
So in unit-test, we can mock TwitchClient
:
@RunWith(MockitoJUnitRunner.class)
public class TwitchServiceTest {
@Mock
private TwitchClient mockedTwitchClient;
// Tested instance
private TwitchService twitchService;
@Before
public void before() {
twitchService = new TwitchService(mockedTwitchClient);
}
@Test
public void ourTest() {
when(mockedTwitchClient.xyz()).thenReturn(...);
...
}
and in the real code, we "inject" real TwitchClient
built by TwitchClientBuilder
:
...
twitchService = new TwitchService(TwitchClientBuilder.builder().build());
...
Upvotes: 1