IllegalStateException:在同一方法中进行两次调用时缺少行为定义

IllegalStateException: missing behavior definition when having a double call in same method

public class Holder() {

    Contact contact1;
    Contact contact2;
}

public class ContactServiceImpl() {

    public Contact create(Contact contact) {
        // do create
    }
}

public class HolderServiceImpl() {
    ContactService contactService = new ContactServiceImpl();

    public Holder createHolder(Holder holder) {
        contactService.create(holder.getContact1());
        contactService.create(holder.getContact2());

        return holder;
    }
}

pulbic class HolderServiceTest() {
    ContactServiceImpl contactService = new ContactServiceImpl();
    HolderServiceImpl holderService = new HolderServiceImpl();

    @Before
    public void setUp() {
        contactService = EasyMock.createMock(ContactServiceImpl.class);     
        holderService.setContactServiceImpl(contactService);
        EasyMock.expect(contactService.create(EasyMock.isA(Contact.class))).andReturn(new Contact()).anyTimes();
    }

    @Test
    public void testCreate() {
        Holder holder = new Holder();

        holderService.create(holder)
    }
}

当没有设置回放时,我在第二次调用 contactService.create 时出错,这是 IllegalStateException。

但是添加时(在 expect 调用之后):

EasyMock.replay(contactService);

我收到此错误:

Unexpected method call ContactServiceImpl.create(Contact@4ebd441a[

我尝试使用 PowerMock,但我遇到了同样的问题。甚至有可能同时进行这样的通话吗? Anytimes() 似乎存在这种用途,但效果不佳。

您从未将模拟置于重播状态。只需在 setUp 方法的末尾添加 EasyMock.replay(contactService);

实际上错误的是我的方法 testCreate 缺少 contact1 和 contact2 上的 setter,这导致了错误。

我可以选择:

  1. 设置两个对象
  2. 使用 EasyMock.isNull(Contact.class) 而不是 EasyMock.isA(Contact.class).

然而,由于在实际情况下可能将其中之一设为 null,因此最好的解决方案是使用 EasyMock.anyObject(Contact.class ) 接受初始化对象或空值。

@Before
public void setUp() {
    contactService = EasyMock.createMock(ContactServiceImpl.class);     
    holderService.setContactServiceImpl(contactService);
    EasyMock.expect(contactService.create(EasyMock.anyObject(Contact.class))).andReturn(new Contact()).anyTimes();
}