Issue
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?
Solution
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
Answered By - g00glen00b
Answer Checked By - David Marino (JavaFixing Volunteer)