Java 多次模拟时,Mockito UnfinishedStubbingException
我想在发票类中存根Method GenerateReferenceEnumber():Java 多次模拟时,Mockito UnfinishedStubbingException,java,mockito,stub,spy,Java,Mockito,Stub,Spy,我想在发票类中存根Method GenerateReferenceEnumber(): public class Invoice { private String id; private String referenceNumber; private Date issueDate; private PaymentMethod paymentMethod; private Date paymentDate; private String shopI
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();
}
}
公共类发票{
私有字符串id;
私有字符串引用编号;
非公开发行日期;
私人付费方式付费方式;
私人日期付款日期;
私人字符串shopId;
私人物品清单;
私人发票状态;
public void moveToNextState(){
status=status.nextState();
}
public void generateReferenceNumber(){
if(referenceNumber!=null){
回来
}
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();
}
私有流buildApprovedInvoice(){
val approvedInvoices=新的ArrayList();
对于(int i=0;i<10;i++){
val发票=发票.builder().build();
val spy=spy(发票);
doAnswer(调用->{
最终发票模拟=(发票)调用.getMock();
mock.setReferenceNumber(“发票参考号”);
返回null;
}).when(spy).GenerateReferenceEnumber();
批准的发票。添加(间谍);
}
返回已批准的发票。stream();
}
当我执行测试时,我得到以下错误:
org.mockito.exceptions.misusing.unfinishedstubingexception:
此处检测到未完成的存根:
->在com.coroscan.core.services.invoice.invoicessendingservicetest.sendvoices(invoicessendingservicetest.java:54)
例如,可能缺少return()。正确的短截线示例:
when(mock.isOk())。然后返回(true);
when(mock.isOk()).thenthow(异常);
doThrow(异常).when(模拟).someVoidMethod()
有人知道为什么吗
谢谢。您不需要模拟发票来测试它。或者,如果是单元测试,您可以模拟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");
}
}
单元测试(模拟发票参考):
公共类发票{
私有字符串id;
私有字符串引用编号;
非公开发行日期;
私人付费方式付费方式;
私人日期付款日期;
私人字符串shopId;
私人物品清单;
私人发票状态;
public void moveToNextState(){
status=status.nextState();
}
public void generateReferenceNumber(){
if(referenceNumber!=null){
回来
}
getInvoiceReference().createNew(issueDate.toString();
}
公共发票引用getInvoiceReference(){
返回新的InvoiceReference();
}
}
课堂测试{
私人发票;
@嘲弄
私人发票参考发票参考;
@之前
无效设置(){
发票=新发票();
initMocks(this);
when(invoiceReference.createNew(any(Date.class))。然后返回(“测试参考号”);
}
@试验
当ReferenceEnumbereQualsNull()时,void应设置ReferenceNumber\u{
发票。setIssueDate(新日期());
invoice.GenerateReferenceEnumber();
资产(发票).hasFieldWithValue(“参考编号”、“测试参考编号”);
}
@试验
当ReferenceEnumberisNoteQualsNull()时,void不应设置ReferenceNumber\u{
发票.设置参考编号(“不同的参考编号”);
invoice.GenerateReferenceEnumber();
资产(发票).hasFieldWithValue(“参考编号”、“不同参考编号”);
}
}
当我调用new InvoiceReference()时,我真的不知道如何模拟InvoiceReference。你能解释一下吗?嗯,我明白了,但我可以,我真的不想构建一个InvoiceReference getter。我的帖子更多的是关于我为什么要使用Mockito的doAnswer()是不正确的。但是谢谢你的帮助。Alexandre Liscia然后只使用第一个解决方案(没有模仿InvoiceReference)你能解释一下为什么这不起作用吗?还有,我不想测试Invoice,但想测试一个使用它的服务。我很确定异常不是来自你问题中显示的代码。你能提供一个生成异常的方法吗?
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");
}
}