代码之家  ›  专栏  ›  技术社区  ›  Othello

Java:为什么这个单元测试不起作用(一对多关系)?

  •  0
  • Othello  · 技术社区  · 2 年前

    我有以下与java单元测试相关的代码

        @Test
        public void testFindPetsByOwner() {
            CustomerDTO customerDTO = createCustomerDTO();
            CustomerDTO newCustomer = userController.saveCustomer(customerDTO);
    
            PetDTO petDTO = createPetDTO();
            petDTO.setOwnerId(newCustomer.getId());
            PetDTO newPet = petController.savePet(petDTO);
            petDTO.setType(PetType.DOG);
            petDTO.setName("DogName");
            PetDTO newPet2 = petController.savePet(petDTO);
    
            List<PetDTO> pets = petController.getPetsByOwner(newCustomer.getId());
            Assertions.assertEquals(pets.size(), 2);
            Assertions.assertEquals(pets.get(0).getOwnerId(), newCustomer.getId());
            Assertions.assertEquals(pets.get(0).getId(), newPet.getId());
        }
    

    最后一次assert.equals的结果失败,如下所示

    
    org.opentest4j.AssertionFailedError: 
    Expected :1
    Actual   :2
    <Click to see difference>
    
    

    PetController.java

        @PostMapping
        public PetDTO savePet(@RequestBody PetDTO petDTO) {
    
            Pet newPet = new Pet();
            BeanUtils.copyProperties(petDTO, newPet, "id");
            Pet savedPet = petService.save(newPet);
            BeanUtils.copyProperties(savedPet, petDTO);
            return petDTO;
        }
    
        @GetMapping("/owner/{ownerId}")
        public List<PetDTO> getPetsByOwner(@PathVariable long ownerId) {
    
            List<Pet> petsByOwner = petService.getPetsByOwner(ownerId);
            List<PetDTO> petDTOList = new ArrayList<>();
            for(Pet pet:petsByOwner){
                PetDTO petDTO = new PetDTO();
                BeanUtils.copyProperties(pet, petDTO);
                petDTOList.add(petDTO);
            }
            return petDTOList;
        }
    

    PetService.java

        public Pet save(Pet pet){
    
            Customer customer = customerRepository.findById(pet.getOwnerId()).orElseThrow(() -> new CustomerNotFoundException());
    
            pet.setCustomer(customer);
            customer.getPets().add(pet);
            customerRepository.save(customer);
            List<Pet> savedPets =  customer.getPets();
            Pet nPet =  savedPets.get(savedPets.size() - 1 );
            return nPet;
        }
    
        public List<Pet> getPetsByOwner(long ownerId) {
            return petRepository.findByOwnerId(ownerId);
        }
    

    PetDTO.java

    public class PetDTO {
        private long id;
        private PetType type;
        private String name;
        private long ownerId;
        private LocalDate birthDate;
        private String notes;
    // getters and setters
    }
    

    Pet.java

    @Entity
    public class Pet {
    
        @Id
        @GeneratedValue(strategy = GenerationType.SEQUENCE)
        private long id;
    
        @NotNull
        @Enumerated(EnumType.STRING)
        private PetType type;
    
        private String name;
        
        private long ownerId;
    
        private LocalDate birthDate;
    
        private String notes;
    
        @ManyToMany(mappedBy = "pets")
        private List<Schedule> schedules;
    
        @ManyToOne(fetch = FetchType.EAGER)
        @JoinColumn(name = "customer_id")
        private Customer customer;
    //getters and setters
    }
    

    客户.java

    @Entity
    public class Customer extends Person {
    
        private String phoneNumber;
    
        private String notes;
        
        @OneToMany(fetch = FetchType.LAZY, mappedBy = "customer", cascade = CascadeType.ALL )
        private List<Pet> pets = new ArrayList<>();
    //getters and setters
    }
    

    Person.java

    @MappedSuperclass
    public class Person {
    
        @Id
        // watch out if this generation strategy becomes a bug later
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        protected long id;
        @Nationalized
        private String name;
    ...
    }
    

    PetRepository.java

    @Repository
    public interface PetRepository extends JpaRepository<Pet, Long> {
    
        List<Pet> findByOwnerId(long ownerId);
        
    }
    

    下面可以看到与该bug相关的类。我怀疑这个错误可能与单元测试中的传递引用有关。 注意:我已经编辑了帖子,添加了其中一位投稿人要求的相关课程

    1 回复  |  直到 2 年前
        1
  •  1
  •   D-Dᴙum    2 年前

    在测试中,当您调用时,您假设的是结果的顺序:

    List<PetDTO> pets = petController.getPetsByOwner(newCustomer.getId());
    

    在方法中看不到查询 getPetsByOwner() 我认为没有应用排序,也没有按降序应用排序。如果您看不到代码,或者无法保证有任何订购,那么您应该将测试更改为以下内容:

    int pet1Id = newPet.getId();
    int pet2Id = newPet2.getId();
    for (PetDto pet : pets) {
        if (pet.getID() == newPet.getId() {
             //newPet specific tests
        } else if (pet.getId() == newPet2.getId() {
            // newPet2 specific tests
        } else {
            throw new RuntimeException("Unexpected ID");
        }
    }
    

    还要确保您的值在断言中的顺序正确,否则会导致日志消息混乱。