Использование @Mock и @InjectMocks - PullRequest
35 голосов
/ 31 января 2012

В настоящее время я изучаю фреймворк Mockito и создал несколько тестовых случаев с использованием Mockito. Но потом я прочитал, что вместо вызова mock ( SomeClass .class) я могу использовать @Mock и @InjectMocks - единственное, что мне нужно сделать, - это аннотировать мой тестовый класс с помощью @RunWith(MockitoJUnitRunner.class) или используйте MockitoAnnotations.initMocks(this); в методе @Before.

Но это не работает - кажется, что @Mock не будет работать! Вот мои 2 ревизии кодов - одна с аннотациями, а другая без.

Что я делаю не так?

public class ReportServiceImplTestMockito {

    private TaskService       mockTaskService; // This is the Mock object
    private ReportServiceImpl service;

    @Before
    public void init(){
        service         = new ReportServiceImpl();
        mockTaskService = mock(TaskServiceImpl.class);
        service.setTaskServiceImpl(mockTaskService);
    }
/// ...

 Some tests
}

Как я уже сказал - эта работа великолепна. Но следующее не будет:

@RunWith(MockitoJUnitRunner.class)
public class ReportServiceImplTestMockito {

     @Mock 
     private TaskService      mockTaskService;

     @InjectMocks 
     private ReportServiceImpl service;

         // Some tests
}

А вот класс ReportServiceImpl:

@Service
public class ReportServiceImpl implements ReportService {

    @Autowired
    private TaskService taskServiceImpl;

    public ReportServiceImpl(){}

    public ReportServiceImpl(TaskService taskService){
        this.taskServiceImpl = taskService;
    }

    public void setTaskServiceImpl(TaskService taskServiceImpl) {
        this.taskServiceImpl = taskServiceImpl;
    }
}

Чего мне не хватает?

Ответы [ 3 ]

27 голосов
/ 27 марта 2012

О.К., я понял свою ошибку !!! Я использовал @InjectMocks, но инициализировал ту же переменную в методе init () ... Так что случилось, что mockito ввел фиктивные объекты в мою переменную - но через несколько секунд я запустил ее - инициализировав ту же самую переменную !!!

12 голосов
/ 31 января 2012

Ваш код отлично работает для меня, используя Mockito 1.9.

Используя версию Mockito 1.8+, я получаю очень конкретное сообщение об ошибке, в котором точно указывается, как решить проблему. Как подсказывает php-кодер: для Mockito 1.8+ вам нужно инициализировать поле.

Вы видели это или любое другое сообщение об ошибке?

Edit:

У меня работает следующий код. Небольшие изменения:

  • Удалены весенние аннотации
  • Удален интерфейс
  • Добавлен геттер
  • Добавлено пусто TaskService
  • Добавлен тест с System.out.println

Это выдает ошибку для вас? :

Услуги:

public class ReportServiceImpl {

    private TaskService taskServiceImpl;


    public ReportServiceImpl() {

    }


    public ReportServiceImpl(TaskService taskService) {
        this.taskServiceImpl = taskService;
    }


    public void setTaskServiceImpl(TaskService taskServiceImpl) {
        this.taskServiceImpl = taskServiceImpl;
    }


    public TaskService getTaskServiceImpl() {
        return taskServiceImpl;
    }
}

Зависимость:

public class TaskService {

}

Тест, отпечатки mockTaskService:

@RunWith(MockitoJUnitRunner.class)
public class ReportServiceImplTestMockito {

    @Mock
    private TaskService       mockTaskService;

    @InjectMocks
    private ReportServiceImpl service;


    @Test
    public void testMockInjected() {
        System.out.println(service.getTaskServiceImpl());
    }
}
3 голосов
/ 31 января 2012

Я не уверен, но попробуйте создать новый экземпляр ReportServiceImpl вручную (как вы сделали в рабочем примере):

 @InjectMocks 
 private ReportServiceImpl service = new ReportServiceImpl();
...