Reputation: 113
Hy guys,
I am trying to make a test using mockito on a web application that uses spring mvc. When it executes this line "Mockito.reset(notificacaoRepositoryMock);" it throws "org.mockito.exceptions.misusing.NotAMockException: Argument should be a mock, but is: class com.sun.proxy.$Proxy40"
I saw that in am example and it worked, I can't find what I am doing wrong here.
@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();
}
My TestContext is:
@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);
}
}
The class I want mock is a CrudRepository interface
public interface NotificacaoRepository extends CrudRepository<Notificacao, Long> {
}
and, I think, the relevant part of my pom.xml is (spring versions and 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>
UPDATE
@jfcorugedo i tryed exactly what you said but I keep receiving the same error. My test context is just
@Configuration
public class TestContext {
@Bean
@Primary
public NotificacaoRepository notificacaoRepository() {
return Mockito.mock(NotificacaoRepository.class);
}
}
and my test class now is:
@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();
}
Upvotes: 3
Views: 6203
Reputation: 10061
As far as I know, you are trying to replace the spring bean with a mock version.
In that case you have to annotate the method that produces your mock with the annotation @Primary
, so Spring could choose the mock object by default in each autowired field (of course if it doesn't have any qualifier).
If you're trying to use a Spring context in your test that has some real beans and other mock beans, you have to follow this steps:
@Configuration
class in your test folder that inject a mock instance of the beans you want to mockFor instance:
Configuration class that injects the mock
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);
}
}
Test 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;
...
}
Upvotes: 0
Reputation: 1205
This is because Spring create a proxy around your bean.
Try to not inject mock using 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();
}
Upvotes: 2