嘿伙计们,
我正在尝试在使用弹簧 mvc 的 Web 应用程序上使用 mockito 进行测试。当它执行此行"Mockito.reset(notificacaoRepositoryMock);"时,它会抛出"org.mockito.exceptions.misusing.NotAMockException:参数应该是模拟的,但是是:classcom.sun.proxy.$Proxy 40"
我在我的例子中看到了这一点并且它奏效了,我在这里找不到我做错了什么。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {TestContext.class, WebAppConfig.class})
@WebAppConfiguration
public class NotificacaoControllerTest {
private MockMvc mockMvc;
@Autowired
private NotificacaoRepository notificacaoRepositoryMock;
@Autowired
private WebApplicationContext webApplicationContext;
@Before
public void setUp() {
// *** Error here ***
Mockito.reset(notificacaoRepositoryMock);
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
我的测试上下文是:
@Configuration
public class TestContext {
@Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("i18n/messages");
messageSource.setUseCodeAsDefaultMessage(true);
return messageSource;
}
@Bean
public NotificacaoRepository notificacaoRepository() {
return Mockito.mock(NotificacaoRepository.class);
}
}
我想要模拟的类是一个 CrudRepository 接口
public interface NotificacaoRepository extends CrudRepository<Notificacao, Long> {
}
而且,我认为,我的pom的相关部分.xml是(春季版本和mockito)
<properties>
<hibernate.version>4.2.0.Final</hibernate.version>
<mysql.connector.version>5.1.21</mysql.connector.version>
<spring.version>4.1.6.RELEASE</spring.version>
<spring.data.version>1.8.0.RELEASE</spring.data.version>
</properties>
...
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>${spring.data.version}</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>1.9.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>3.2.3.RELEASE</version>
<scope>test</scope>
</dependency>
更新
@jfcorugedo我完全按照你说的做了尝试,但我不断收到同样的错误。我的测试上下文只是
@Configuration
public class TestContext {
@Bean
@Primary
public NotificacaoRepository notificacaoRepository() {
return Mockito.mock(NotificacaoRepository.class);
}
}
我现在的测试课是:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {WebAppConfig.class})
@WebAppConfiguration
@Import({TestContext.class})
public class NotificacaoControllerTest {
@Autowired
NotificacaoRepository notificacaoRepositoryMock;
@Before
public void setUp() {
Mockito.reset(notificacaoRepositoryMock); // Error >> org.mockito.exceptions.misusing.NotAMockException: Argument should be a mock, but is: class com.sun.proxy.$Proxy55
this.mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
这是因为 Spring 会在你的 bean 周围创建一个代理。
尽量不要使用 Spring 注入模拟
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {TestContext.class, WebAppConfig.class})
@WebAppConfiguration
public class NotificacaoControllerTest {
private MockMvc mockMvc;
private NotificacaoRepository notificacaoRepositoryMock;
@Autowired
private WebApplicationContext webApplicationContext;
@Before
public void setUp() {
notificacaoRepositoryMock = Mockito.mock(NotificacaoRepository.class);
Mockito.reset(notificacaoRepositoryMock);
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
据我所知,您正在尝试用模拟版本替换春豆。
在这种情况下,您必须使用注释@Primary
注释生成模拟的方法,因此 Spring 可以在每个自动连线字段中默认选择模拟对象(当然,如果它没有任何限定符)。
如果您尝试在测试中使用包含一些真实 bean 和其他模拟 bean 的 Spring 上下文,则必须按照以下步骤操作:
- 在测试文件夹中创建一个
@Configuration
类,用于注入要模拟的 Bean 的模拟实例 - 在测试中导入此配置类
例如:
注入模拟的配置类
import static org.mockito.Mockito.mock;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import xxx.xxx.xxx.NotificacaoRepository;
@Configuration
public class MockConfigurer {
@Bean
@Primary
public NotificacaoRepository registerMock() {
return mock(NotificacaoRepository.class);
}
}
测试类
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {WebAppConfig.class})
@WebAppConfiguration
@Import({MockConfigurer.class})
public class NotificacaoControllerTest {
//Now the instance injected here should be a mock object
@Autowired
private NotificacaoRepository notificacaoRepositoryMock;
...
}