我刚刚遇到一个复杂的问题,因为我开始在基于Spring FW4的Java应用程序中对一些Controller-Methods进行单元测试。
我的ApplicationConfig.java注释了@Configuration和@EnableTransactionManagement(proxyTargetClass = true)和一个公共Controller方法,我创建它来保存一个简单的实体类的新对象是testet与下面的ControllerTestClass
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(locations = {"classpath:/test-context.xml"})
@TransactionConfiguration(defaultRollback = true, transactionManager = "annotationDrivenTransactionManager")
public class TestController
@Autowired
public MyClassService myClassServiceMock;
protected MockMvc mockMvc;
@Autowired
protected WebApplicationContext webApplicationContext;
@Before
public void setUp() throws Exception {
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
};
@org.junit.Before
public void reset() {
Mockito.reset(myClassServiceMock);
}
@org.junit.After
public void after() {
verifyNoMoreInteractions(myClassServiceMock);
}
@Test
public void testSaveObject() throws Exception {
MyObject object = new MyObjectBuilder().withName("object").withDate("2014-08-15").build();
when(myClassServiceMock.createObject(objectName, objectDate)).thenReturn(object);
[.. mockMvcTest which works ... ]
verify(myclassServiceMock, times(1)).createObject(objectName, objectDate);
}
}
debug.log的以下部分是我无法弄清问题的原因,但当我删除@ EnableTransactionManager-Annotation时,没有错误发生...
2014-08-15_17:25:59.608 [main] DEBUG o.s.orm.jpa.JpaTransactionManager - Creating new transaction with name [a.b.c.MyClassService$$EnhancerByMockitoWithCGLIB$$cf62a86c.saveObject]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
2014-08-15_17:25:59.608 [main] DEBUG o.s.orm.jpa.JpaTransactionManager - Opened new EntityManager [org.hibernate.jpa.internal.EntityManagerImpl@513f39c] for JPA transaction
2014-08-15_17:25:59.616 [main] DEBUG o.s.orm.jpa.JpaTransactionManager - Exposing JPA transaction as JDBC transaction [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle@320cac01]
2014-08-15_17:25:59.618 [main] DEBUG o.s.orm.jpa.JpaTransactionManager - Initiating transaction commit
2014-08-15_17:25:59.618 [main] DEBUG o.s.orm.jpa.JpaTransactionManager - Committing JPA transaction on EntityManager [org.hibernate.jpa.internal.EntityManagerImpl@513f39c]
2014-08-15_17:25:59.633 [main] DEBUG o.s.orm.jpa.JpaTransactionManager - Closing JPA EntityManager [org.hibernate.jpa.internal.EntityManagerImpl@513f39c] after transaction
2014-08-15_17:25:59.633 [main] DEBUG o.s.o.jpa.EntityManagerFactoryUtils - Closing JPA EntityManager
2014-08-15_17:25:59.635 [main] DEBUG o.s.t.c.s.DirtiesContextTestExecutionListener - After test method: context [DefaultTestContext@8f72029 testClass = MyControllerTest, testInstance = a.b.c.MyControllerTest@453204e6, testMethod = testSaveObject@MyClassControllerTest, testException = org.mockito.exceptions.misusing.UnfinishedVerificationException:
Missing method call for verify(mock) here:
-> at a.b.c.MyClassService$$FastClassBySpringCGLIB$$809f2bf.invoke(<generated>)
Example of correct verification:
verify(mock).doSomething()
我真的很感激一些帮助,因为我的奇怪和研究已经持续了几天:(
由于
答案 0 :(得分:2)
首先,你没有在测试中初始化Mockito。 Read this post
您需要致电MockitoAnnotations.initMocks()
,因为您已经在使用@RunWith(SpringJUnit4ClassRunner.class)
并且您只能在班级上指定一名选手。
@Before
public void reset() {
MockitoAnnotations.initMocks(this);
// Mockito.reset(myClassServiceMock); <= remove this line
}
我认为你也想在这个模拟中使用@Mock而不是@Autowired,这样你就可以拥有一个Mockito模拟实例,然后你可以调用verify()
。您还必须将myClassServiceMock
注入您正在测试的班级(即控制器)
@Mock
public MyClassService myClassServiceMock;
您可以删除对Mockito.reset()的调用,因为@Mock将为每个测试方法创建一个新实例。
如果您打算使用@Autowired
并从应用程序上下文中检索MyClassService实例,那么您将无法调用任何Mockito方法,例如verify()。
我还希望@TransactionConfiguration
不是必需的,因为你永远不会访问你的数据库(因为你正在嘲笑你的服务层),所以你可以删除它。如果您在测试中遇到了数据库,那么这是一个不同的故事,但我无法通过您提供的代码告诉您。