当前位置: 首页 > 知识库问答 >
问题:

需要在POSTendpoint跳过@RequestBody注释中模拟服务方法

柳梓
2023-03-14

我正在尝试为一个POST RESTendpoint编写一个单元测试。我需要用mockito模拟一个在上面的endpoint使用的服务方法。使用模拟mvc触发endpoint。

我正在嘲弄endpoint中使用的userService.saveUser(user)并返回一个整数作为创建的userID。但模拟似乎总是返回0而不是7777(userId deifinated)。对于“verify”,它表示“参数不同!”它在endpoint和我定义的模拟中传递给userService(用户)。

Mockito验证错误:

Argument(s) are different! Wanted:
userService.saveUser(
    com.foo.dto.User@741f8dbe
);
-> at com.foo.controller.UserControllerTest.saveUser(UserControllerTest.java:104)
Actual invocation has different arguments:
userService.saveUser(
    com.foo.dto.User@212dfd39
);
-> at com.foo.controller.UserController.saveUser(UserController.java:45)

Comparison Failure:  <Click to see difference>

我猜这是因为@RequestBody注释创建了一个全新的User对象。这会导致无法运行“UserService”模拟。(如果我错了,请更正我)

我可能需要做一些工作来触发endpoint,并将“User”对象传递给“UserService”,因为它是在测试类中定义的,并且跳过@RequestBody注释。

谁能指导我度过这一关吗?如有任何帮助,我们将不胜感激。

endpoint:

@PostMapping("/users")
public ResponseEntity<String> saveUser(@RequestBody User user){

    int userId = userService.saveUser(user);

    return new ResponseEntity<>("User created. Id: "+ userId, HttpStatus.CREATED);
}

测试类:

@RunWith(SpringJUnit4ClassRunner.class)
public class UserControllerTest {
    @InjectMocks
    private UserController userController;
    @Mock
    private UserService userService;
    private ObjectMapper mapper;
    private MockMvc mockMvc;
    private Integer userId = 7777;

    @Before
    public void setUp() throws Exception{
        MockitoAnnotations.initMocks(this);
        this.mockMvc = MockMvcBuilders.standaloneSetup(userController).build();
        mapper = new ObjectMapper();

        user = new User();
        user.setName("DummyUser");
    }

    @Test
    public void saveUser(){
        when(userService.saveUser(user)).thenReturn(userId);
        this.mockMvc.perform(post("/users")
                .accept(MediaType.TEXT_PLAIN)
                .contentType(MediaType.APPLICATION_JSON)
                .content(mapper.writeValueAsString(user)))
                .andExpect(status().isCreated())
                .andExpect(content()
                       .contentTypeCompatibleWith(MediaType.TEXT_PLAIN))
                .andExpect(content().string("User created. Id: "+userId));
        verify(userService).saveUser(user);
    }

}

共有1个答案

彭正谊
2023-03-14

我想原因就是你说的那个。您可以做的是使用一个匹配器传递给您的mock,这样它将返回您想要的东西,只要它接收到一个特定类型的对象(而不是一个特定对象:

import static org.mockito.ArgumentMatchers.any;
...
when(userService.saveUser(any(User.class))).thenReturn(userId);

当您正在使用它时,模拟将返回您想要的内容,只有当它接收您在执行when时传递的特定对象作为调用的参数时。正如您从所拥有的异常中看到的,模拟期望接收一个引用com.foo.dto.user@741f8dbe的对象(这是您正在安装方法中创建的对象),但它接收的是com.foo.dto.user@212dfd39,这是jackson反序列化rest调用主体时生成的对象。

 类似资料:
  • 我使用的是改型2.1,当我调用@get时,它会说 现在..如果我定义@retrofit.http.get,它将抛出 以及方法 分级文件

  • 问题内容: 我写了一个AngularJS服务,我想对其进行单元测试。 我的app.js文件已注册: 我可以测试DI是否像这样工作: 这证明了可以通过DI框架创建服务,但是接下来我要对服务进行单元测试,这意味着要模拟注入的对象。 我该怎么做呢? 我试过将我的模拟对象放在模块中,例如 并将服务定义重写为: 但是后者似乎停止了DI所创建的所有服务。 有人知道我可以如何为单元测试模拟注入的服务吗? 谢谢

  • 有人能解释一下Spring3中的和注释吗?它们是干什么用的?任何例子都很好。

  • 我正在尝试用以下结构为我的服务创建一个舵手图: 安装helm chart后,部署和服务已成功创建,但virtualservice尚未创建。 我的 istio 虚拟服务 yaml 文件如下所示: 令人惊讶的是,如果我在helm安装完成部署应用程序之后应用上面的yaml,那么就会创建virtualservice。 请帮我调试这个问题,如果需要更多的调试信息,请告诉我。

  • 问题内容: 用csv.DictReader处理CSV文件很棒- 但是我有带注释行的CSV文件(在行的开头用哈希表示),例如: csv模块不包含任何跳过此类行的方法。 我可以轻松地做些骇人听闻的事情,但是我想有一种将csv.DicReader包装在其他迭代器对象周围的好方法,该对象会进行预处理以丢弃行。 问题答案: 实际上,这与:

  • 人们经常会问AspectJ这样的问题,所以我想在以后可以轻松链接到的地方回答。 我有这个标记注释: 现在我像这样注释接口和/或方法: 这是一个小驱动程序应用程序,它也实现了接口: 现在当我定义这个方面时,我希望它被触发 对于带注释类的每个构造函数执行和 每次执行带注释的方法。 不幸的是,方面没有打印任何内容,就像类