How to use JMock to test mocked methods inside a m

2019-07-16 19:03发布

I'm having trouble determining how to mock a particular piece of code.

Here is my method:

public void sendNotifications(NotificationType type, Person person)
    {
        List<Notification> notifications = findNotifications(type);
        for(Notification notification : notifications)
        {
            notification.send(person);
        }
    }

I would like to be able to use JMock to test that findNotifications is called and that and returns the expected value and that send() is called.

findNotifications calls my Dao which is mocked. Notification is an abstract class.

I have a unit test like this, but it's obviously not working. It satisfies the first two expectations but no more.

    @Test
public void testSendNotifications2()
{
    final Person person = new Person();
    notificationEntries.add(createEntry1);

    Mockery context = new JUnit4Mockery() {{ setImposteriser(ClassImposteriser.INSTANCE); }};
    final NotificationDao dao = context.mock(NotificationDao.class, "notificationDao");
    final Notification mockedNotification = context.mock(V2ADTNotification.class, "mockNotification");
    notifications.add(mockedNotification);

    final NotifierServiceImpl mockedService = context.mock(NotifierServiceImpl.class, "mockedService");

    //NotifierService service = new NotifierServiceImpl(dao);

    context.checking(new Expectations() {
        {
            one(mockedService).setDao(dao);
            one(mockedService).sendNotifications(NotificationType.CREATE, person);
            one(mockedService).findNotifications(NotificationType.CREATE);
            one(dao).getByNotificationType(NotificationType.CREATE);
            will(returnValue(notificationEntries)); 
            will(returnValue(notifications));

            one(mockedNotification).send(person);
        }
    });

    mockedService.setDao(dao);
    mockedService.sendNotifications(NotificationType.CREATE, person);
    context.assertIsSatisfied();
}

    mockedService.sendNotifications(NotificationType.CREATE, person);
    context.assertIsSatisfied();
}

How could I get this to work as I want it to?

Another way I tried. It satisfies the first two expectations but not the send one.

@Test
public void testSendNotifications()
{
    final Person person = new Person();
    notificationEntries.add(createEntry1);

    Mockery context = new JUnit4Mockery() {{ setImposteriser(ClassImposteriser.INSTANCE); }};
    final NotificationDao dao = context.mock(NotificationDao.class, "notificationDao");
    final Notification mockedNotification = context.mock(V2ADTNotification.class, "mockNotification");

    NotifierService service = new NotifierServiceImpl(dao);

    context.checking(new Expectations() {
        {
            one(dao).getByNotificationType(NotificationType.CREATE);
            will(returnValue(notificationEntries)); 

            one(mockedNotification).send(person);
        }
    });

    service.sendNotifications(NotificationType.CREATE, person);
    context.assertIsSatisfied();
}

I'm pretty new to using Jmock so I apologize if it doesn't look like I have much of a clue as to what I'm doing (I don't).

1条回答
三岁会撩人
2楼-- · 2019-07-16 19:21

test mocked methods inside a mocked method.

You really just can't do that. The calls in the real method aren't being made, because you're calling the mock instead of the real method.

Your first attempt fails the last two expectations because the calls that would make them pass are made only in the real implementation of sendNotifications, and not in the mock that you made of it.

The second is closer to workable, but you need to add your mockedNotification to the notificationEntries list that you've set up to be return by the mock of getByNotificationType.

查看更多
登录 后发表回答