Как я могу издеваться над некоторыми вызовами методов bean-компонента, но использовать определенный bean-компонент в других вызовах методов того же тестового класса? - PullRequest
1 голос
/ 09 апреля 2019

Я пытаюсь проверить интерфейс службы, который имеет указанную реализацию в TestConfiguration. Сервисный интерфейс получает интерфейс DAO, который также имеет указанную реализацию в TestConfiguration. Реализация Службы определяется как реальная служба, которая будет работать, в то время как Test DAO - это новая пользовательская реализация интерфейса.

В 95% случаев я хочу использовать тестовую реализацию DAO. Однако в некоторых тестах я хочу переопределить функциональность DAO. Поскольку существует так мало случаев, когда я хочу переопределить DAO, я хочу просто имитировать использование Mockito на условной основе, не создавая другую реализацию интерфейса DAO (для крайних случаев, таких как возврат пустого списка из DAO). В идеале они должны быть в том же классе, который предназначен для тестирования Сервиса.

Я попытался использовать аннотацию @Spy для компонента DAO в классе тестирования. Я пытался использовать @MockBean для компонента DAO. Однако я попытался использовать doReturn от Mockito и, когда функциональность перезаписывает реализацию DAO по умолчанию, я всегда получаю результат от реализации Test DAO, определенной в TestConfiguration.

Я изменил текст того, что я делаю, так как это код компании, но это именно то, что я пытаюсь сделать иначе.

Моя TestConfiguration определена так

@TestConfiguration
public class TestAppConfiguration {

    @Bean
    public PersonService personService() {
        return new PersonServiceImpl(personDao());
    }  

    @Bean
    public PersonDao personDao() {
        return new TestPersonDaoImpl();
    }
}

Моя реализация сервиса выглядит следующим образом

public class PersonServiceImpl implements PersonService {
    private Logger logger = LoggerFactory.getLogger(PersonServiceImpl.class);

    private PersonDao personDao;

    public PersonServiceImpl(PersonDao personDao){
        this.personDao = personDao;
    }

    @Override
    public List<PersonDto> getAllPersons() {
        return personDao.findAll().stream()
                .map(person -> PersonDtoFactory.getPersonDto(person))
                .collect(Collectors.toList());
    }

    @Override
    public PersonDto getPersonById(Long id) {
       return PersonDtoFactory.getPersonDto(personDao.findById(id));

    }
}

Моя тестовая реализация DAO выглядит следующим образом

public class TestPersonDaoImpl implements PersonDao {

    @Override
    public List<PersonModel> findAll() {
        return getPersons();
    }

    @Override
    public List<PersonModel> findById(id) {
        return getPersons().stream()
                       .filter(person -> person.getId() == id)
                                   .collect(Collectors.toList());
    }

    private List<PersonModel> getPersons() {
        List<PersonModel> personList = new ArrayList<>();
        personList.add(new PersonModel(1L, "Susan");
        personList.add(new PersonModel(2L, "Jerry");
        personList.add(new PersonModel(3L, "Tom");
        return personList;
    }
}

И вот, наконец, мой тестовый класс обслуживания

@RunWith(SpringRunner.class)
@Import(TestAppConfiguration.class)
public class PersonServiceTests {
    //We won't test web socket functionality in this test class.
    @Autowired
    private PersonService personService;

    @MockBean //want to overwrite in the test only when specified in the test, otherwise, use default TestPersonDaoImpl bean.
    private PersonDao personDao;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void getAllPersons() {
        assert(personService.getAllTests().size() > 0);
    }

    @Test
    public void getPersonById() {
        assert(personService.getPersonById(1L).getName().equals("Susan"));
    }

    @Test
    public void getAllPersons_NoPersons(){
        //Mock the DAO call since it will have all of the test data by default
        doReturn(new ArrayList<Person>()).when(personDao).findAll();
        //when(personDao.findAll()).thenReturn(new ArrayList<>());  <-- this also doesn't work
        assert(personService.getAllPersons().size() == 0);
}

Ожидается, что все тесты пройдут, и вызов DAO будет перезаписан при вызове в реализации сервиса. Фактическим результатом является то, что первые два теста пройдены, а третий тест не пройден, поскольку он не перезаписывает вызов dao.

1 Ответ

1 голос
/ 09 апреля 2019

С @MockBean вы получите внедренный инсценированный экземпляр.

С @Spy ваш дао не будет введен в сервис

Вам нужно @SpyBean .. вы получитеинъекция и все методы, вызываемые по умолчанию.

...