簡體   English   中英

Mockito使用spring mvc注入拋出NotAMockException

[英]Mockito throws NotAMockException using spring mvc injection

Hy伙計們,

我試圖在使用spring mvc的web應用程序上使用mockito進行測試。 當它執行這行“Mockito.reset(notificacaoRepositoryMock);”時 它拋出“org.mockito.exceptions.misusing.NotAMockException:Argument應該是一個模擬,但是:class com.sun.proxy。$ Proxy40”

我在例子中看到它並且它起作用了,我找不到我在這里做錯了什么。

@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();
    }

我的TestContext是:

@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);
        }
}

我想要mock的類是一個CrudRepository接口

public interface NotificacaoRepository extends CrudRepository<Notificacao, Long> {
}

而且,我認為,我的pom.xml的相關部分是(spring版本和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我完全按照你所說的嘗試,但我一直收到同樣的錯誤。 我的測試環境是正確的

@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注入mock

@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();
    }

據我所知,你試圖用模擬版本替換 spring bean。

在這種情況下,您必須使用注釋@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;

    ...
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM