2

我正在使用 testNg 和 Mockito 编写单元案例。我面临的问题是使用下面给出的方法:

public void publishRequest(final NotificationRequest request){

    MessageCreator messageCreator = new MessageCreator() {

        @Override
        public Message createMessage(Session session) throws JMSException {
            if (logger.isDebugEnabled()) {
                logger.debug("Start of MessagePublisher publishRequest");
            }
            ObjectMessage msg = session.createObjectMessage();

            msg.setStringProperty(
                    "SELECTOR",
                    request.getAvailaibilityTier() + "-"
                            + request.getEsbReference());

            if (logger.isDebugEnabled()) {
            logger.debug("Message Selector=>"+msg.getStringProperty("SELECTOR"));
            }

            msg.setStringProperty(NotificationConstants.CACHE_KEY.name(),
                    request.getId());

            msg.setObject(request.getData());
            if (logger.isDebugEnabled()) {
                logger.debug("Publishing request -->" + request);
            }

            if (logger.isDebugEnabled()) {
                logger.debug("End of MessagePublisher publishRequest");
            }
            return msg;
        }
    };
    producerTemplate.send(messageCreator);
}

在编写单元案例时,即使我的测试案例创建了 MessageCreater 对象,也不会调用 createMessage() 方法。我想将它也包含在我的单位案例中以获得更好的覆盖范围。任何想法如何测试内部类方法?

4

2 回答 2

5

可以说,anynomous 内部类是该publishRequest方法的实现细节。在进行单元测试时,您将通过测试合同publishRequest而不是内部实现来获得更健壮的测试。正如@vtheron 建议的那样,要测试您的MessageCreator,您必须将其提取到它自己的类中。但除此之外,还要考虑在课堂上“注入”对您的引用MessageCreator。这样,您就可以单独测试您的publishRequestMessageCreator单独的。就个人而言,我更喜欢在构造函数中“注入”此类依赖项,但还有其他方法可以实现相同的目的。我会做这样的事情:

public class MyClass {
    private MessageCreator messageCreator;

    public MyClass(MessageCreator messageCreator) {
        this.messageCreator = messageCreator;
    }

    public void publishRequest(final NotificationRequest request) {
        producerTemplate.send(messageCreator);
    }
}

MessageCreator然后,您可以在测试中简单地向您的班级发送“模拟” :

public class MyTest {

    @Test
    public void testPublish() {
        MessageCreator mock = new MessageCreator() { // Mock impl (or use a mock library)};
        MyClass classToTest = new MyClass(mock);
        classToTest.publishRequest(notificationRequest);
        // Do assertions and verify
    }
}

它仍在测试您的publishRequest方法的内部结构(测试void方法倾向于),但是如果您可以制定类似的合同

发布请求时,应将消息发送到队列

而不是

publishRequest 应该创建一个 MessageCreator 并创建一个由生产者发送的消息

至少你有一个更抽象的方法来编写测试,从长远来看,这将明确地影响你编写测试的方式。

于 2013-04-10T08:21:57.833 回答
1

如果您觉得需要测试匿名类的行为,请将其移到 publishRequest 方法之外,使其成为顶级类或包含您的 publishRequest 方法的类中的静态类。

于 2013-04-10T05:08:23.203 回答