Jpa 单元测试 - 服务 - 实体管理器 null

Jpa unit test - Service - entity manager null

这是我试过的:

@RunWith(SpringRunner.class)
@DataJpaTest
@ActiveProfiles("h2")
@Rollback(false)
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
public class ServiceTest {

    private EntityManager entityManager;

    public ServiceTest(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    @Test
    public void findLocation() {

        Location location  = entityManager.find(Location.class, 2);

        assertEquals(location.getName(), "Avenue");
    }
    @Test
    public void updateLocation() {

        Location location = entityManager.find(Location.class, 2);
        location.setNo_people(10);
        entityManager.persist(location);
        entityManager.flush();
    }
    
}

我得到的错误是' Runner org.junit.internal.runners.ErrorReportingRunner(用于 class com.unibuc。AWBD_Project_v1.services.ServiceTest)不支持过滤,因此将是 运行 完全地。测试 class 应该只有一个 public 零参数构造函数'

这是定位服务:

@Service
public class LocationService implements BaseService<Location> {
    private final LocationRepository locationRepository;

    @Autowired
    public LocationService(com.unibuc.AWBD_Project_v1.repositories.LocationRepository locationRepository) {
        this.locationRepository = locationRepository;
    }

    @Override
    public Location insert(Location object) {
        return locationRepository.save(object);
    }

    @Override
    public Location update(Long id, Location updatedObject) {
        var foundId =  locationRepository.findById(id);

        return foundId.map(locationRepository::save).orElse(null);
    }

    @Override
    public List<Location> getAll() {
        return locationRepository.findAll();
    }

    @Override
    public Optional<Location> getById(Long id) {
        return locationRepository.findById(id);
    }

    @Override
    public void deleteById(Long id)
    {
        try {
            locationRepository.deleteById(id);
        } catch (LocationException e) {
            throw  new LocationException("Location not found");
        }
    }

    @Override
    public Page<Location> findAll(int page, int size, String sortBy, String sortType){
        Sort sort = sortType.equalsIgnoreCase(Sort.Direction.ASC.name()) ? Sort.by(sortBy).ascending() :
                Sort.by(sortBy).descending();
        Pageable pageable = PageRequest.of(page - 1, size, sort);
        return  locationRepository.findAll(pageable);
    }

}

您好,您的测试代码有3个问题。

1 您应该从测试构造函数中删除 EntityManager entityManager 以进行可运行的测试 class.

2 如果你想在你的测试中使用 entityManager class 你应该 @Autowired 它

public class ServiceTest {
    @Autowired
    private EntityManager entityManager;

3 看起来您正在测试 entityManager 而不是您的 LocationService 在单元测试中,您应该使用 Mockito

模拟 entityManager 等依赖项

您似乎想创建一个集成测试。

一次服务集成测试的3个步骤(以findLocation()为例)

  1. 准备测试数据库中的数据 创建一个新的位置对象并使用 entityManager 或 testEntityManager 将其保存到数据库中。

  2. 在 id 上执行你的 findLocation 方法 不要忘记自动装配您的服务 class.

  3. 验证检索到的数据是否符合预期 将检索到的位置对象与您保存的位置对象进行比较。

这是代码

@RunWith(SpringRunner.class)
@DataJpaTest
@ActiveProfiles("h2")
@Rollback(false)
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
public class ServiceTest {
    @Autowired
    private EntityManager entityManager;
    @Autowired  
    private LocationService locationService;

    public ServiceTest() {
        
    }

    @Test
    public void findLocation() {
        //given

        Location location  = new Location(....);
        entityManager.save(location);

        //when
        Location foundLocation=locationService.getById(location.getId());
        //then
        assertTrue(foundLocation.isPresent());
        assertEquals(foundLocation.get().getName(), "Avenue");
    }

如果您有任何问题,我可以为您提供帮助。