Reputation: 79
I have a method in the service class that uses an external wrapper to call the slack api. The wrapper I'm using is this one if it makes any difference. This is how I'm using the wrapper,
//This is the method in my service class
public String sendMess(SlackObj obj) {
//SlackObj contains the channel url, channel name and the message
//build the payload from the SlackObj
//Slack is the name of the wrapper's class that I'm using
Slack slack = Slack.getInstance();
//slack.send is the method that sends the message to slack
WebhookResponse res = slack.send(url, payload);
//other logic
}
//This is what I've tried
@Test
public void slackSendMessageTest(){
//build the slack obj and payload
//build the mock WebhookResponse
Slack slackMock = mock(Slack.class)
when(slackMock.send(channelUrl, payload)).thenReturn(mockWebHookRes);
assertEquals("SUCCESS", testService.sendMessage(testSlackObj);
}
I am trying to write some tests for this method, so my question is, how would i test it without having the message sent every time I run the test? I believe the cause of this is because slack itself is not mocked and I have no idea as how to inject the mock into the mocked service class.
I am open to refactoring the service class if it helps with the testing. Any suggestions and recommendation is appreciated. Thanks.
Upvotes: 0
Views: 2818
Reputation: 31720
You are going to have to find a way to mock Slack
, which appears to be a singleton, unfortunately.
Here's what I would do:
1) Make Slack
available as a bean that can be autowired:
@Configuration
public class SlackConfiguration {
@Bean
public Slack slack() {
return Slack.getInstance();
}
}
2) Change your class to take an injected Slack
:
Note that I am totally guessing on the name here, as you just show the method. You would inject the Slack
object you turned into a @Bean
above, and not use Slack.getInstance()
directly anywhere else.
@Component
public class SlackService {
private final Slack slack;
@Autowired
public SlackService(final Slack slack) {
this.slack = slack;
}
public String sendMessage(final Object message) {
final WebhookResponse res = slack.send(url, payload);
// etc
}
}
3) Mock the Slack
object and pass it to your SlackService
in test:
This allows you to mock out the implementation of Slack
, so you can alter its behavior. I won't go into mocking in detail.
public class SlacServiceTest {
private final Slack slack = mock(Slack.class);
private final SlackService serviceUnderTest = new SlackService(slack);
@Test
public void testSomething() {
// TODO: set mock responses here
// Given... when... then...
}
}
Upvotes: 5