【问题标题】:Mock: when() requires an argument which has to be 'a method call on a mock'模拟:when() 需要一个参数,该参数必须是“模拟上的方法调用”
【发布时间】:2016-02-07 21:59:04
【问题描述】:

我正在为我的 REST-API 编写单元测试,并且在实体创建模拟方面遇到了一些问题。我不知道如何模拟 EntityManager。我尝试了下面的示例,但出现错误。

我的控制器测试:

public class MControllerTest {

    private MockMvc mockMvc;

    @InjectMocks A a;
    @InjectMocks B b;
    @InjectMocks AController aController;
    @InjectMocks private AServiceImpl aServiceImpl;

    @Autowired WebApplicationContext webApplicationContext;
    @Autowired private FilterChainProxy springSecurityFilterChain;

    @Autowired
    @InjectMocks
    private EntityManagerFactory entityManagerFactory;


    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
                                 .addFilter(springSecurityFilterChain)
                                 .build();
    }

    @Test
    public void postATest() throws Exception {

        a.setDDDD("XXX");

        EntityManagerFactory entityManagerFactory = webApplicationContext.getBean(EntityManagerFactory.class);
        EntityManager entityManager = entityManagerFactory.createEntityManager();
        when(this.entityManagerFactory.createEntityManager()).thenReturn(entityManager);

        when(aServiceImpl.createEntity(isA(A.class))).thenReturn(a);

        b.setCCCC;
        a.setMovieTranslations(Arrays.asList(b));

        when(aServiceImpl.createEntity(isA(B.class))).thenReturn(a);

        mockMvc.perform(post("/path")
               .andExpect(status().isOk())
               .andReturn().getResponse().getContentAsString();
    }

createEntity 方法:

public Object createEntity(T t) {
    try {
        entityManager.persist(t);
        return t;
    } catch (IllegalArgumentException | EntityExistsException | ...
}

错误日志:

org.mockito.exceptions.misusing.MissingMethodInvocationException: 
when() requires an argument which has to be 'a method call on a mock'.
For example:
    when(mock.getArticles()).thenReturn(articles);

Also, this error might show up because:
1. you stub either of: final/private/equals()/hashCode() methods.
   Those methods *cannot* be stubbed/verified.
   Mocking methods declared on non-public parent classes is not supported.
2. inside when() you don't call method on mock but on some other object.

    at com.x.server.controller.MControllerTest.postATest(MControllerTest.java:121)

当我不在 EntityManager 上注入模拟对象时,我通过persist 方法得到一个空指针异常,并带有此错误日志:

java.lang.NullPointerException: null
    at com.x.server.serviceImpl.AManageServiceImpl.createEntity(AManageServiceImpl.java:45)
    at com.eza.server.controller.MControllerTest.postATest(MControllerTest.java:123)

有人可以帮我吗?

【问题讨论】:

  • 我想知道你为什么要像这样混合 Spring 和 Mockito。要么你需要这些“真正的”bean,然后你正在创建一个集成测试,你很可能不需要 mockito。或者您正在创建一个单元测试,其中每个依赖的 bean 都被模拟。
  • 你是对的。谢谢。你的评论解决了我的问题。它现在正在工作。我现在只使用 mockito。
  • 很高兴听到。请用您现在工作的代码以及您所做的更改写一个答案,以便未来的读者可以从中学习:)。

标签: java spring unit-testing spring-boot mocking


【解决方案1】:

解决它。我刚刚使用 entitymanager 接口删除了一些代码行,它可以工作。

public class MControllerTest {

    private MockMvc mockMvc;

    @InjectMocks A a;
    @InjectMocks B b;
    @InjectMocks AController aController;

    @Autowired WebApplicationContext webApplicationContext;
    @Autowired private FilterChainProxy springSecurityFilterChain;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
                                 .addFilter(springSecurityFilterChain)
                                 .build();
    }

    @Test
    public void postMovieTest() throws Exception {

        a.setDDDD("XXX");
        b.setCCCC;
        a.setMList(Arrays.asList(b));


        mockMvc.perform(post("/path")
            .content(asJsonString(a))
            .contentType(MediaType.APPLICATION_JSON)
            .accept(MediaType.APPLICATION_JSON)
            .andExpect(status().isOk())
            .andReturn().getResponse().getContentAsString();
    }

asJsonString 是我自己编写的方法来转换 json 中的对象

干杯

【讨论】:

  • 无法理解,你改变了什么。你能解释一下吗?
猜你喜欢
  • 1970-01-01
  • 2017-05-08
  • 1970-01-01
  • 2012-02-29
  • 2020-05-12
  • 2018-09-03
  • 1970-01-01
  • 2017-10-19
相关资源
最近更新 更多