我想在我的发票类中对methot generateReferenceNumber()进行存根:
public class Invoice {
private String id;
private String referenceNumber;
private Date issueDate;
private PaymentMethod paymentMethod;
private Date paymentDate;
private String shopId;
private List<InvoiceGroupItem> groupItems;
private InvoiceStatus status;
public void moveToNextState() {
status = status.nextState();
}
public void generateReferenceNumber() {
if (referenceNumber != null) {
return;
}
referenceNumber = new InvoiceReference().createNew(issueDate).toString();
}
}
此对象用于我要测试的服务中。为此,我需要多张发票。所以我写了以下代码:
private Stream<Invoice> buildApprovedInvoice() {
val approvedInvoices = new ArrayList<Invoice>();
for (int i = 0; i < 10; i++) {
val invoice = Invoice.builder().build();
val spy = spy(invoice);
doAnswer(invocation -> {
final Invoice mock = (Invoice) invocation.getMock();
mock.setReferenceNumber("Invoice reference number");
return null;
}).when(spy).generateReferenceNumber();
approvedInvoices.add(spy);
}
return approvedInvoices.stream();
}
并且当我执行测试时,出现以下错误:
org.mockito.exceptions.misusing.UnfinishedStubbingException:在此处检测到未完成的存根:-> com.coruscant.core.services.invoice.InvoiceSendingServiceTest.sendInvoices(InvoiceSendingServiceTest.java:54)
例如thenReturn()可能会丢失。正确存根的示例:when(mock.isOk())。thenReturn(true);when(mock.isOk())。thenThrow(exception);doThrow(exception).when(mock).someVoidMethod();
任何人都知道为什么吗?
谢谢。
您无需模拟Invoice
即可对其进行测试。或者,如果是单元测试,则可以模拟InvoiceReference
。如果是集成测试:
class Test {
private Invoice invoice;
@BeforeEach
void setUp() {
invoice - new Invoice();
}
@Test
void shouldSetReferenceNumber_WhenReferenceNumberEqualsNull() {
invoice.setIssueDate(new Date());
invoice.generateReferenceNumber();
assertThat(invoice).hasFieldWithValue("referenceNumber", expectingValue);
}
@Test
void shouldNotSetReferenceNumber_WhenReferenceNumberIsNotEqualsNull() {
invoice.setReferenceNumber("test-reference-number");
invoice.generateReferenceNumber();
assertThat(invoice).hasFieldWithValue("referenceNumber", "test-reference-number");
}
}
单元测试(模拟发票参考):
public class Invoice {
private String id;
private String referenceNumber;
private Date issueDate;
private PaymentMethod paymentMethod;
private Date paymentDate;
private String shopId;
private List<InvoiceGroupItem> groupItems;
private InvoiceStatus status;
public void moveToNextState() {
status = status.nextState();
}
public void generateReferenceNumber() {
if (referenceNumber != null) {
return;
}
getInvoiceReference().createNew(issueDate).toString();
}
public InvoiceReference getInvoiceReference() {
return new InvoiceReference();
}
}
class Test {
private Invoice invoice;
@Mock
private InvoiceReference invoiceReference;
@BeforeEach
void setUp() {
invoice = new Invoice();
MockitoAnnotations.initMocks(this);
when(invoiceReference.createNew(any(Date.class)).thenReturn("test-reference-number");
}
@Test
void shouldSetReferenceNumber_WhenReferenceNumberEqualsNull() {
invoice.setIssueDate(new Date());
invoice.generateReferenceNumber();
assertThat(invoice).hasFieldWithValue("referenceNumber", "test-reference-number");
}
@Test
void shouldNotSetReferenceNumber_WhenReferenceNumberIsNotEqualsNull() {
invoice.setReferenceNumber("different_reference_number");
invoice.generateReferenceNumber();
assertThat(invoice).hasFieldWithValue("referenceNumber", "different_reference_number");
}
}