弹簧+ Mockito测试注射



我的问题与向Spring bean中注入mock mock中提出的问题非常相似。事实上,我相信公认的答案可能对我有用。然而,我对这个答案有一个问题,然后再做一些进一步的解释,以防这个答案实际上不是我的答案。

所以我按照前面提到的链接找到了Springockito的网站。我修改了我的test-config.xml,以包含类似于以下内容:

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:mockito="http://www.mockito.org/spring/mockito"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.mockito.org/spring/mockito http://www.mockito.org/spring/mockito.xsd">
...
    <mockito:mock id="accountService" class="org.kubek2k.account.DefaultAccountService" />
...
</beans>

目前www.mockito.org重定向似乎有问题,所以我在https://bitbucket.org/kubek2k/springockito/raw/16143b32095b/src/main/resources/spring/mockito.xsd找到了XSD代码,并更改了xsi:schemaLocation中的最后一个条目,以指向这个位桶链接。

运行mvn test会产生以下错误(为了可读性添加了换行符):

Caused by: org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException:
    Line 43 in XML document from class path resource [spring/test-context.xml] is invalid;
    nested exception is org.xml.sax.SAXParseException; lineNumber: 43; columnNumber: 91;
    The prefix "mockito" for element "mockito:mock" is not bound.

所以关于Springockito的问题是:是否有可能再包含这个?我错过了什么?

现在,进一步解释…

我有一个接口,我想测试它的实现:

public interface MobileService {
    public Login login(Login login);
    public User getUser(String accessCode, Date birthDate);
}

实现包含了Spring @Autowire为我提供的DAO:

@Service
public class MobileServiceImpl implements MobileService {
    private MobileDao mobileDao;
    @Autowired
    public void setMobileDao(MobileDao mobileDao) {
        this.mobileDao = mobileDao;
    }
}

我不想改变我的接口来包含setMobileDao方法,因为那将只是添加代码来支持我的单元测试。我试图模拟DAO,因为这里的实际SUT是ServiceImpl。我怎样才能做到这一点呢?

您不想测试您的接口:它根本不包含任何代码。您想要测试您的实现。setter是可用的。就用它吧:

@Test
public void testLogin() {
    MobileServiceImpl toTest = new MobileServiceImpl();
    toTest.setMobileDao(mockMobileDao);
    // TODO call the login method and check that it works as expected.
}

不需要spring上下文。只需实例化您的POJO服务,手动注入模拟依赖,并测试您想要测试的方法。

在与springckitto XSD问题斗争了一段时间后,我发现了一个更简单的解决方案。让Spring使用工厂方法为您注入mock,即在applicationContext.xml中put:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
  <bean class="org.mockito.Mockito" factory-method="mock">
    <constructor-arg value="com.gerrydevstory.mycoolbank.AccountsDAO"/>
  </bean>
  <bean class="com.gerrydevstory.mycoolbank.BankingService"/>
</beans>

将AccountsDAO bean注入到BankingService类中。对应的JUnit测试用例是:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/BankingServiceTest.xml")
public class BankingServiceTest {
  @Autowired private BankingService bankingService;
  @Autowired private AccountsDAO mockAccountsDAO;
  @Test
  public void testTransfer() throws Exception {
    // Setup 2 accounts
    Account acc1 = new Account();
    acc1.setBalance(800.00);
    Account acc2 = new Account();
    acc2.setBalance(200.00);
    // Tell mock DAO to return above accounts when 1011 or 2041 is queried respectively
    when(mockAccountsDAO.findById(1011)).thenReturn(acc1);
    when(mockAccountsDAO.findById(2041)).thenReturn(acc2);
    // Invoke the method to test
    bankingService.transfer(1011, 2041, 500.00);
    // Verify the money has been transferred
    assertEquals(300.00, acc1.getBalance(), 0.001);
    assertEquals(700.00, acc2.getBalance(), 0.001);
  }
}

我个人觉得这很优雅,很容易理解。

设置模拟dao有三个选项:

  1. 测试实现—它通过setDao方法为mock提供了一个接缝。(作为JB的回答)
  2. 将setDao方法添加到接口—不希望这样做,因为您不想仅仅为了支持测试而添加代码。
  3. 在impl类中添加一个构造函数以接受dao -不需要的原因与#2相同。

如果你想做#3,你需要给MobileService添加一个构造函数,让它接受MobileDao。

   public MobileServiceImpl(MobileDao mobileDao) {
    this.mobileDao = mobileDao;
}

那么你的测试将看起来像这样:

import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.*;
import java.util.Date;
import org.junit.Before;
import org.junit.Test;
public class MobileServiceImplTest {
    private MobileService systemUnderTest;
    private MobileDao mobileDao;
    @Before
    public void setup() {
        mobileDao = mock(MobileDao.class);
        systemUnderTest = new MobileServiceImpl(mobileDao);
    }
    @Test
    public void testGetUser() {
        //if you need to, configure mock behavior here. 
        //i.e. when(mobileDao.someMethod(someObject)).thenReturn(someResponse);
        systemUnderTest.getUser("accessCode", new Date());
        verify(mobileDao).getUser("JeffAtwood");
    }
}

请注意,您没有向我们提供MobileDao的详细信息,因此我创建了一个getUser方法,该方法接受一个String。

要使测试通过,您的MobileServiceImpl只需要这样:

mobileDao.getUser("JeffAtwood");

问题似乎是你的类路径不包含实际的springckito jar -你不必更改URL -这些只是spring内部使用的令牌-它们没有被解决-所有你需要的是一个足够新的spring发行版和springckito在类路径上。

Kuba(前面提到的lib的创建者:))

我有同样的问题,我想使用springckito根据他们的wiki,但验证xml抛出错误。所以当我试着去xsd应该在的地方时,它没有。所以我读了这个,并开始使用这个:

xmlns:mockito="http://www.mockito.org/spring/mockito"
xsi:schemaLocation="http://www.mockito.org/spring/mockito 
    https://bitbucket.org/kubek2k/springockito/raw/16143b32095b/src/main/resources/spring/mockito.xsd">

但是当我看到这个链接,有不好的感觉。在我看来,这不是永久稳定的链接(你必须检查如果我错了)

相关内容

  • 没有找到相关文章

最新更新