Home > OS >  Unit test for Service PUT method doesn't work Spring Boot application
Unit test for Service PUT method doesn't work Spring Boot application

Time:08-24

I made my Unit Test for my service, testing PUT method using JUnit5 (Note that given static import is from DBBMockito and verify static import is from Mockito. Also I used @Builder to made the objects.). Please take a look at the current test:

@ExtendWith(MockitoExtension.class)
class BillServiceTest {

    @Mock
    private BillRepository billRepository;

    @InjectMocks
    private BillService billService;

    @Test
    void whenGivenId_shouldUpdateBill_ifFound() {
        Bill bill =
                Bill.builder()
                        .billId(70L)
                        .hospitalServicesDescription("Cardiology")
                        .price(100)
                        .build();

        Bill newBill =
                Bill.builder()
                        .price(400)
                        .build();

        given(billRepository.findById(bill.getBillId())).willReturn(Optional.of(bill));
        billService.updateBill(bill.getBillId(), newBill);

        verify(billRepository).save(newBill);
        verify(billRepository).findById(bill.getBillId());
    }
}

When I run this I get a report that the arguments are different:

Argument(s) are different! Wanted:
billRepository.save(
    Bill(billId=null, dateOfBill=null, hospitalServicesDescription=null, price=400, patient=null)
);
-> at com.app.hospitalmanagementsystem.service.BillServiceTest.whenGivenId_shouldUpdateBill_ifFound(BillServiceTest.java:96)
Actual invocations have different arguments:
billRepository.findById(
    70L
);
-> at com.app.hospitalmanagementsystem.service.BillService.updateBill(BillService.java:44)
billRepository.save(
    Bill(billId=70, dateOfBill=null, hospitalServicesDescription=null, price=400, patient=null)
);
-> at com.app.hospitalmanagementsystem.service.BillService.updateBill(BillService.java:49)

Comparison Failure: 
<Click to see difference>

When I click on <Click to see difference> , this is what I get:

Expected:

billRepository.save(
    Bill(billId=null, dateOfBill=null, hospitalServicesDescription=null, price=400, patient=null)
);

Actual:

billRepository.findById(
    70L
);
billRepository.save(
    Bill(billId=70, dateOfBill=null, hospitalServicesDescription=null, price=400, patient=null)
);

Also, the code which I am trying to test is here:

@Service
public class BillService {

    private final BillRepository billRepository;

    @Autowired
    public BillService(BillRepository billRepository) {
        this.billRepository = billRepository;
    }


    public Bill updateBill(Long billId, Bill billUpdatedDetails) {
        Bill updatedBill = billRepository.findById(billId)
                .orElseThrow(()-> new ResourceNotFoundException("Bill with id "   billId   " doesn't exist."));
        updatedBill.setDateOfBill(billUpdatedDetails.getDateOfBill());
        updatedBill.setHospitalServicesDescription(billUpdatedDetails.getHospitalServicesDescription());
        updatedBill.setPrice(billUpdatedDetails.getPrice());
        return billRepository.save(updatedBill);
    }

This is the Entity:

@Entity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Builder
@Table(
        name = "bill"
)
public class Bill {

    @Id
    @SequenceGenerator(
            name = "bill_sequence",
            sequenceName = "bill_sequence",
            allocationSize = 1
    )
    @GeneratedValue(
            strategy = GenerationType.SEQUENCE,
            generator = "bill_sequence"
    )
    private Long billId;
    @Column(
            name = "date_of_bill",
            nullable = false
    )
    private LocalDate dateOfBill;
    @Column(
            name = "hospital_services_description",
            nullable = false
    )
    private String hospitalServicesDescription;
    @Column(
            name = "price",
            nullable = false
    )
    private Integer price;

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(
            name = "patient_id",
            referencedColumnName = "patientId"
    )
    private Patient patient;

    @JsonIgnore
    @OneToMany(mappedBy = "bill")
    @ToString.Exclude
    private List<PatientMedicalHistory> patientMedicalHistories;

    public void connectPatient(Patient patient) {
        this.patient = patient;
    }
}

Does anyone have an idea how I can solve this?

CodePudding user response:

In your code, the argument passed to billRepository.save() is updatedBill. updatedBill comes from billRepository.findById():

public Bill updateBill(Long billId, Bill billUpdatedDetails) {
    // updatedBill comes from billRepository.findById()
    Bill updatedBill = billRepository
        .findById(billId)
        .orElseThrow(()-> new ResourceNotFoundException("..."));
    // ...
    // updatedBill is passed to billRepository.save()
    return billRepository.save(updatedBill);
}

In your test, you make sure that billRepository.findById() returns bill:

given(billRepository.findById(bill.getBillId())).willReturn(Optional.of(bill));
// ...

So that means that the argument passed to billRepository.save() should also be bill. However, in your test you passed newBill in stead of bill, which is why the test fails:

verify(billRepository).save(newBill); // Incorrect
verify(billRepository).save(bill); // Correct
  • Related