Q:Mockito - Using @Mock and @Autowired

Viewed 630

I'd like to test a service class which has two other service classes like as below using Mockito.

@Service
public class GreetingService {

    private final Hello1Service hello1Service;
    private final Hello2Service hello2Service;

    @Autowired
    public GreetingService(Hello1Service hello1Service, Hello2Service hello2Service) {
        this.hello1Service = hello1Service;
        this.hello2Service = hello2Service;
    }

    public String greet(int i) {
        return hello1Service.hello(i) + " " + hello2Service.hello(i);
    }
}

@Service
public class Hello1Service {

    public String hello(int i) {

        if (i == 0) {
            return "Hello1.";
        }

        return "Hello1 Hello1.";
    }
}

@Service
public class Hello2Service {

    public String hello(int i) {

        if (i == 0) {
            return "Hello2.";
        }

    return "Hello2 Hello2.";
    }
}    

I know how to mock Hello1Service.class and Hello2Service.class with Mockito like as below.

@RunWith(MockitoJUnitRunner.class)
public class GreetingServiceTest {

    @InjectMocks
    private GreetingService greetingService;

    @Mock
    private Hello1Service hello1Service;

    @Mock
    private Hello2Service hello2Service;

    @Test
    public void test() {

        when(hello1Service.hello(anyInt())).thenReturn("Mock Hello1.");
        when(hello2Service.hello(anyInt())).thenReturn("Mock Hello2.");

        assertThat(greetingService.greet(0), is("Mock Hello1. Mock Hello2."));
    }
}

I'd like to mock Hello1Service.class and inject Hello2Service.class using @Autowired like as below. I tired to use @SpringBootTest but it did not work. Is there a better way?

@RunWith(MockitoJUnitRunner.class)
public class GreetingServiceTest {

    @InjectMocks
    private GreetingService greetingService;

    @Mock
    private Hello1Service hello1Service;

    @Autowired
    private Hello2Service hello2Service;

    @Test
    public void test() {

        when(hello1Service.hello(anyInt())).thenReturn("Mock Hello1.");
        assertThat(greetingService.greet(0), is("Mock Hello1. Hello2."));
    }
}
2 Answers

You can change with Spy for real object instead of Mock. Test code will be like this;

@RunWith(MockitoJUnitRunner.class)
public class GreetingServiceTest {

    @InjectMocks
    private GreetingService greetingService;

    @Mock
    private Hello1Service hello1Service;

    @Spy
    private Hello2Service hello2Service;

    @Test
    public void test() {

        when(hello1Service.hello(anyInt())).thenReturn("Mock Hello1.");
        assertThat(greetingService.greet(0), is("Mock Hello1. Hello2."));
    }
}
Related