需要使用Junit测试MailService

时间:2015-07-09 19:16:33

标签: java spring junit javamail

我将如何使用Junit进行测试?我对如何使用xml文件进行设置感到困惑。

public void sendMailHire(User user, Job job){

    String email = user.getEmail();

    ApplicationContext mailContext = new ClassPathXmlApplicationContext(
            SPRING_MAIL_XML);

        try {
            Courier courier = (Courier) mailContext.getBean(COURIER);
            courier.sendMail(
                email,
                "Congratulations!",
                "Dear "
                    + user.getFirstName()
                    + " "
                    + user.getLastName()
                    + ", \n\nIt is our honor to inform you that you have been chosen for the position "
                    + job.getJobName()
                    + ".  Please contact our office for Orientation information.\nHuman Resources\nTechWannaBees\n(123) 456-7890");
        } finally {
            ((AbstractApplicationContext) mailContext).close();
        }

}

测试mailContext已关闭的JUnit测试

1 个答案:

答案 0 :(得分:2)

如果您的预期测试结果是方法调用(如调用方法close()),那么您需要一种名为模拟的技术。

您有两种选择:

  • 撰写您自己的模拟工具集
  • 使用现有模拟库(例如 Mockito EasyMock PowerMock 等)

简而言之: Mock 对象是“假”对象,它们实现真实的接口,但模拟特定的行为。

为了将模拟对象交给您的代码,您必须避免在代码中调用new。因此我换了 new ClassPathXmlApplicationContext(SPRING_MAIL_XML)applicationContextFactory.create(SPRING_MAIL_XML)

您的测试(使用Mockito 1.9.5)可能如下所示:

import org.junit.Test;
import static org.mockito.Mockito.*;

public class MailerTest {

    @Test
    public void test() {

        // create mock objects
        ApplicationContextFactory factoryMock = mock(ApplicationContextFactory.class);
        ApplicationContext contextMock = mock(ApplicationContext.class);
        Courier courierMock = mock(Courier.class);

        // define behaviour of mocked objects
        when(factoryMock.create(anyString())).thenReturn(contextMock);
        when(contextMock.getBean(anyString())).thenReturn(courierMock);

        // run the production code
        new Mailer().sendMailHire(new User(), new Job(), factoryMock);

        // verify, that close has been called
        verify(contextMock).close();
    }

}

如果您将代码更改为以下内容:

interface ApplicationContextFactory {
    ApplicationContext create(String springMailXml);
}

class ApplicationContextFactoryImpl implements ApplicationContextFactory {
    public ApplicationContext create(String springMailXml) {
        return new ClassPathXmlApplicationContext(springMailXml);
    }
}

public class Mailer {

    ...

    public void sendMailHire(User user, Job job, ApplicationContextFactory applicationContextFactory){

        String email = user.getEmail();

        // don't call "new" here - use a factory, that can be mocked
        ApplicationContext mailContext = applicationContextFactory.create(SPRING_MAIL_XML);

        try {
            Courier courier = (Courier) mailContext.getBean(COURIER);
            courier.sendMail(
                    email,
                    "Congratulations!",
                    "Dear "
                            + user.getFirstName()
                            + " "
                            + user.getLastName()
                            + ", \n\nIt is our honor to inform you that you have been chosen for the position "
                            + job.getJobName()
                            + ".  Please contact our office for Orientation information.\nHuman Resources\nTechWannaBees\n(123) 456-7890");
        } finally {
            ((AbstractApplicationContext) mailContext).close();
        }

    }
}