Внедренные Бобы нулевые в абстрактном классе - PullRequest
0 голосов
/ 18 марта 2019

У меня есть служба абстрактного пользователя, в которой я автоматически связал два компонента: Repository и AbstractMapper, но когда я запускаю тестирование для этого класса, все происходит с ошибкой NullPointerException. Например, когда я запускаю сохранение теста для этого сервиса в dubug, оно показывает, что оба bean-компонента имеют нулевое значение. У кого-нибудь была эта проблема? Это мой код:

AbstractService

package com.example.shop.service;

import com.example.shop.dto.AbstractMapper;
import com.example.shop.entity.Identifable;
import com.example.shop.repository.IRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

@Service`enter code here`
public abstract class AbstractService<E extends Identifable, D> implements IService<E, D> {

private IRepository<E> repository;
private AbstractMapper<E, D> abstractMapper;

@Autowired
public AbstractService(IRepository<E> repository, AbstractMapper<E, D> abstractMapper) {
    this.repository = repository;
    this.abstractMapper = abstractMapper;
}

@Override
public D get(Long id) {
    E e = repository.get(id);
    return abstractMapper.entityToDto(e);
}

@Override
public List<D> getAll() {
    List<E> all = repository.getAll();
    List<D> allDtos = all.stream()
            .map(e -> abstractMapper.entityToDto(e))
            .collect(Collectors.toList());
    return allDtos;
}

@Override
public E save(D d) {
    E e = abstractMapper.dtoToEntity(d);
    return repository.save(e);
}

@Override
public E update(D d) {
    E e = abstractMapper.dtoToEntity(d);
    return repository.update(e);
}

@Override
public E delete(D d) {
    E e = abstractMapper.dtoToEntity(d);
    return repository.delete(e);
}

@Override
public void deleteAll() {
    repository.deleteAll();
}
}

UserServiceImpl

package com.example.shop.service;

import com.example.shop.dto.UserDto;
import com.example.shop.dto.UserMapper;
import com.example.shop.entity.User;
import com.example.shop.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
 public class UserServiceImpl extends AbstractService<User, UserDto> implements UserService {

private UserRepository repository;
private UserMapper userMapper;

@Autowired
public UserServiceImpl(UserRepository repository, UserMapper userMapper) {
    super(repository, userMapper);
}
}

Abstract Mapper

package com.example.shop.dto;

import org.springframework.stereotype.Component;

@Component
public interface AbstractMapper<E, D> {

 E dtoToEntity(D d);
 D entityToDto(E e);
 }

Пользователь Mapper:

package com.example.shop.dto;

import com.example.shop.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class UserMapper implements AbstractMapper<User, UserDto> {

private AccountMapper accountMapper;

@Autowired
public UserMapper(AccountMapper accountMapper) {
    this.accountMapper = accountMapper;
}

@Override
public User dtoToEntity(UserDto dto) {
    if (dto == null) {
        return null;
    }
    User user = new User();
    user.setId(dto.getId());
    user.setEmail(dto.getEmail());
    user.setPassword(dto.getPassword());
    user.setLogin(dto.getLogin());
    user.setAccount(accountMapper.dtoToEntity(dto.getAccountDto()));
    return user;
}

@Override
public UserDto entityToDto(User user) {
    if (user == null) {
        return null;
    }
    UserDto dto = new UserDto();
    dto.setEmail(user.getEmail());
    dto.setLogin(user.getLogin());
    dto.setPassword(user.getPassword());
    dto.setId(user.getId());
    dto.setAccountDto(accountMapper.entityToDto(user.getAccount()));
    return dto;
}
}

Класс с @ SpringBootApplication

package com.example.shop;

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ShopApplication implements CommandLineRunner {

public static void main(String[] args) {
    SpringApplication.run(ShopApplication.class, args);
}

@Override
public void run(String... args) throws Exception {
    System.out.println("Test");
}
}

И мои тесты на Сервис:

package com.example.shop.service;

import com.example.shop.dto.UserDto;
import com.example.shop.entity.User;
import com.example.shop.repository.IRepository;
import org.junit.After; 
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import static org.mockito.Mockito.*;

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserServiceImplTest {

private static final Long VALID_ID = 1L;

@Mock
private IRepository<User> repository;

@InjectMocks
private UserServiceImpl service;

@After
public void tearDown() {
    repository.deleteAll();
}

@Test
public void get() {
    service.get(VALID_ID);

    verify(repository, times(1)).get(anyLong());
}

@Test
public void save() {
    UserDto dto = createUser();
    service.save(dto);

    verify(repository, times(1)).save(any());
}

@Test
public void getAll() {
    service.getAll();
    verify(repository, times(1)).getAll();
}

@Test
public void update() {
    UserDto dto = createUser();
    service.update(dto);
    verify(repository, times(1)).update(any());
}

@Test
public void delete() {
    UserDto dto = createUser();
    service.delete(dto);

    verify(repository, times(1)).delete(any());
}

@Test
public void deleteAll() {
    service.deleteAll();

    verify(repository, times(1)).deleteAll();
}

private UserDto createUser() {
    return new UserDto();
}


}

1 Ответ

1 голос
/ 18 марта 2019

Есть несколько проблем с этим кодом. Прежде всего вам не нужно аннотировать абстрактные классы сервисом или компонентом. Абстрактные классы не могут быть созданы, поэтому нет бобов. Второе: автопроводка классов, имеющих дженерики, работать не будет. Как только у вас есть несколько бобов, он больше не будет уникальным. Проверьте, если ваши классы будут созданы. Может быть, вам нужно добавить @componentscan.

Ваш тест находится по адресу: com.example.shop.service, и поэтому он сканирует только бины в этом пакете. Вы должны либо перенести свой тест, либо добавить компоненты с помощью аннотации компонентов

...