Spring MVC Service Junit测试用例

时间:2014-01-15 08:33:12

标签: java spring spring-mvc junit

我正在使用Java Spring MVC应用程序。这是我的服务类。

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.integration.Message;
import org.springframework.integration.MessagingException;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.core.MessageHandler;
import org.springframework.stereotype.Service;

@Service
public class EmailService implements MessageHandler {

    @Autowired
    @Qualifier("receiveChannel")
    private DirectChannel messageChannel;

    private final Log logger = LogFactory
        .getLog(EmailService.class);

    public void init() {
        messageChannel.subscribe(this);
    }

    @Override
    public void handleMessage(Message<?> message) throws MessagingException {
         logger.info("Message: " + message);

    }
}

我想为上面的课写一个测试用例。这就是我试过的

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.web.context.WebApplicationContext;

//other imports

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration("classpath:webapptest")
@ContextConfiguration(locations = {"classpath:test-applicationcontext.xml"})
public class EmailServiceTest {

    @Autowired
    private EmailService emailService;

    @Autowired
    WebApplicationContext wContext;

    @Test
    public void testEmailService() throws Exception {
        emailService=Mockito.spy(new EmailService());
        Mockito.doNothing().when(emailService).init();
    }
}

在我的 applicationcontext.xml 中,我指定了一个Gmail及其密码(启用了IMAP访问)

当我从其他邮件发送邮件中的邮件时,应该只记录邮件(在Service类的其他方法中实现)

当我运行测试用例时,它显示测试用例是成功的。但是,当我向该邮件ID运行任何邮件时,它不会在我的控制台中打印。

2 个答案:

答案 0 :(得分:1)

为什么要加载上下文?如果这不是集成测试,则您不需要(请记住,单元测试需要快速,不能加载/连接到外部资源)。 无论如何,我建议您使用Mockito来模拟DirectChannel并验证交互。

以下是我测试init()方法的方法:

public class EmailServiceTest {

    @Mock
    DirectChannel messageChannel;//you 

    @InjectMocks
    EmailService emailService;

    @Test
    public void shouldSubscribeToSelf(){
       //call method under test
       emailService.init();
       //verify behavior
       Mockito.verify(messageChannel).subscribe(emailService);
    }
}

答案 1 :(得分:1)

正如@isah指出的那样,我认为你在Mock Unit测试和Spring Integration测试之间感到困惑(通常这两者是相互排斥的)。

因为@isah指出这里的模拟方式是正确的集成测试方法:

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.web.context.WebApplicationContext;

//other imports

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration("classpath:webapptest")
@ContextConfiguration(locations = {"classpath:test-applicationcontext.xml"})
public class EmailServiceTest {

    @Autowired
    private EmailService emailService;

    @Autowired
    WebApplicationContext wContext;

    @Test
    public void testEmailService() throws Exception {
        //Spring will automatically wire in emailService.
        emailService.init();
        //validate initialization through whatever external way you can or just be satisified that it didn't throw an exception
    }
}

但我的直觉是你的init()方法应该标记为@PostConstruct,在这种情况下,spring会自动为你执行此操作,因此不是一个好的测试方法(因为它将在测试时执行)启动)。