Я хочу научиться писать тесты JUnit, и у меня ничего не получается.
Это мой тест:
@Test
public void testGetAllCustomers() {
// given
List<Customer> customerList = new ArrayList<Customer>();
customerList.add(c1);
customerList.add(c2);
customerList.add(c3);
given(customerRepository.findAll()).willReturn(customerList);
// when
List<Customer> resultList = customerService.getAllCustomers();
// then
assertThat(resultList).hasSize(3);
}
Проблема в том, что это простое утверждение уже не работает. Возвращаемый список пуст. Я знаю, я новичок во всем этом, но сбой настолько неожиданный с моей точки зрения, что у меня нет подхода, как решить проблему.
Это весь код (не так много):
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
import java.sql.Timestamp;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class CustomerServiceTests {
@Mock
private CustomerRepository customerRepository;
@InjectMocks
private CustomerService customerService;
private Customer c1 = new Customer(
1L,
"Hans Meyer",
false,
Timestamp.from(Instant.now()),
null,
null
);
private Customer c2 = new Customer(
2L,
"Marie Hollande",
true,
Timestamp.from(Instant.now()),
null,
null
);
private Customer c3 = new Customer(
3L,
"Mohammed Abbas",
false,
Timestamp.from(Instant.now()),
null,
null
);
@Before
public void setUp() {
MockitoAnnotations.openMocks(this);
}
@Test
public void testGetAllCustomers() {
// given
List<Customer> customerList = new ArrayList<Customer>();
customerList.add(c1);
customerList.add(c2);
customerList.add(c3);
given(customerRepository.findAll()).willReturn(customerList);
// when
List<Customer> resultList = customerService.getAllCustomers();
// then
assertThat(resultList).hasSize(3);
}
}
Функция для тестирования - это просто, и я знаю, что она работает:
public List<Customer> getAllCustomers() {
return customerRepository.findAll();
}
На самом деле, я просто хочу научиться писать такие тесты, но уже несколько дней не могу их написать. Примеров и объяснений довольно много, но сколько я ни пытался, у меня пока не получилось работающего теста. Как создать рабочий тест для getAllCustomers()? Спасибо за помощь!
Вы инициализируете свои макеты дважды — сначала с помощью @RunWith(MockitoJUnitRunner.class)
, а затем с помощью MockitoAnnotations.openMocks(this);
Это означает, что когда вы вводите свой метод setUp:
И после этого метода
Это означает, что ваш сервис не был повторно инициализирован
Используйте отладчик, чтобы подтвердить это наблюдение.
@InjectMocks javadoc говорит:
MockitoAnnotations.openMocks(this) method has to be called to initialize annotated objects. In above example, openMocks() is called in @Before (JUnit4) method of test's base class. For JUnit3 openMocks() can go to setup() method of a base class. Instead you can also put openMocks() in your JUnit runner (@RunWith) or use the built-in MockitoJUnitRunner.
Вот моя рекомендация: вы должны реорганизовать свой код и применить стиль внедрения конструктора, например:
public class CustomerService {
private final CustomerRepository customerRepository;
public CustomerService(CustomerRepository customerRepository) {
this.customerRepository = customerRepository; // inject customerRepository via constructor
}
// ...
}
тогда вам не нужны никакие аннотации Mockito. Просто удалите их.
public class CustomerServiceTests {
private CustomerRepository customerRepository;
private CustomerService customerService;
// ... init Customer
@Before
public void setup() {
customerRepository = mock(CustomerRepository.class); // inject mocked customerRepository via constructor
customerService = new CustomerService(customerRepository);
}
@Test
public void testGetAllCustomers() {
// same as your test code
}
}
Вы можете видеть, что CustomerServiceTests становится очень простым и тривиальным для тестирования.
Большое спасибо! Ваше объяснение действительно помогает мне лучше понять механизмы. Я также всегда стараюсь заглянуть в документы, но, конечно, с таким объемом информации не так просто уследить, если вы новичок во всем этом.