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

Mockito当...然后返回-返回忽略?

赖诚
2023-03-14

我目前正在学习Spring boot,我一直在测试一个项目——非常感谢任何帮助,因为我是这里的初学者。

我有一个rest控制器测试,使用Mockito,当使用Mockito.when()调用方法时,该测试似乎忽略了Then返回。

这是整个班级:

package com.example.demo.controllers;

import com.example.demo.TestUtils;
import com.example.demo.model.persistence.AppUser;
import com.example.demo.model.persistence.repositories.CartRepository;
import com.example.demo.model.persistence.repositories.UserRepository;
import com.example.demo.model.requests.CreateUserRequest;
import org.junit.Before;
import org.junit.Test;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import java.util.Optional;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;

public class UserControllerTest {

    private UserController userController;
    private UserRepository userRepository = mock(UserRepository.class);
    private CartRepository cartRepository = mock(CartRepository.class);
    private BCryptPasswordEncoder bCryptPasswordEncoder = mock(BCryptPasswordEncoder.class);

    @Before
    public void initTest(){
        userController = new UserController();
        TestUtils.injectObjects(userController, "userRepository", userRepository);
        TestUtils.injectObjects(userController, "cartRepository", cartRepository);
        TestUtils.injectObjects(userController, "bCryptPasswordEncoder", bCryptPasswordEncoder);
        AppUser appUser = TestUtils.getAppUser();
        when(userRepository.findById(0L)).thenReturn(Optional.of(appUser));
        when(bCryptPasswordEncoder.encode("testPassword")).thenReturn("hashedPassword");
    }

    @Test
    public void testFindUserById(){
        ResponseEntity<AppUser> response = userController.findById(0L);
        System.out.println(response);
    }


    @Test
    public void testCreateUser() throws Exception{

        CreateUserRequest createUserRequest = new CreateUserRequest();
        createUserRequest.setUsername("testUser");
        createUserRequest.setPassword("testPassword");
        createUserRequest.setConfirmPassword("testPassword");

        ResponseEntity<AppUser> response = userController.createUser(createUserRequest);

        assertNotNull(response);
        assertEquals(200, response.getStatusCodeValue());

        AppUser createdUser = response.getBody();
        assertNotNull(createdUser);
        assertEquals(0, createdUser.getId());
        assertEquals("testUser", createdUser.getUsername());
        assertEquals("hashedPassword", createdUser.getPassword());
    }
}

名为“testCreateUser”的测试没有问题地通过了。给我一个问题的是名为“testFindUserById”的测试。

以下是我尝试测试的控制器方法(在Postman中测试时,所有方法都可以正常工作):

public ResponseEntity<AppUser> findById(@PathVariable Long id) {
        try{
            log.info("UserIDSearch = " + id);
            System.out.println("UserIDSearch = " + id);
            Optional<AppUser> optionalAppUser = userRepository.findById(id);
            if(optionalAppUser.isPresent()){
                log.info("UserIdFound =  " + id);
                return ResponseEntity.ok(optionalAppUser.get());
            }else{
                throw new ApiException(ExceptionTypes.SEARCHUSER, id.toString());
            }
        }catch(ApiException a){
                return ResponseEntity.notFound().build();
        }
    }

在测试类中被模拟的存储库只是一个简单的JPA假设:

public interface UserRepository extends JpaRepository<AppUser, Long> {
    Optional<AppUser> findByUsername(String username);
    public Optional<AppUser> findById(long id);
}

我运行testFindUserById()测试得到的输出如下:

UserIDSearch = 0
<404 NOT_FOUND Not Found,[]>

我想我在这里想要实现的是,测试使用when()。然后返回()来模拟来自模拟用户存储库的OK响应,但实际上它执行搜索并返回“Not found”。有人能帮忙吗?非常感谢!

共有3个答案

马安邦
2023-03-14

我的案子和你的案子不一样,但我希望能有所帮助。

总结:

mockito对传递的参数是合理的,它对简单或原始数据类型更有效

就我而言,这句话被忽略了:

doReturn(result).when(scriptExecutor).
runScript(connection, new StringReader("selec * from dual;"));

经过几个小时的尝试,我更改了runScript的定义,以接收一个简单的字符串,而不是StringReader。

从这:

public ArrayList runScript(Connection conn, StringReader reader)

为此:

public ArrayList runScript(Connection conn, String query)

然后选择了模拟的句子,一切正常:

doReturn(result).when(scriptExecutor).
runScript(connection, "selec * from dual;");

基本上,如果我使用一个StringReader,没有工作。但是用一个简单的字符串,它就工作了!!

鲁炳
2023-03-14

我认为@Janar是正确的,但我会解释原因。

当您编写“当(userRepository.findById(0L))”时。然后返回(Optional.of(appUser))”,Mockito所做的是设置开始监控对指定方法(findById)的调用,并将参数与“0L”进行比较,这是一个Java长的int,不是一个对象。

实际的方法需要一个java。朗,朗,这是一个物体。这两者并不平等。

正如@Janar建议的那样,您可以通过更改findById方法来修复它,但这不是我要做的。我假设生产代码出于实际原因使用了java.lang.长。相反,我会将测试更改为:

when(userRepository.findById(Long.valueOf(0L))).thenReturn(Optional.of(appUser));
谈琛
2023-03-14

似乎是自动装箱的问题。更改方法public可选

 类似资料:
  • 在编写测试用例时,我使用Mockito模拟某个类。 有没有办法在返回值之前打印一些语句?例如: 上述声明有效,但我无法做到以下几点:

  • 问题内容: 我正在尝试使用“ any”匹配器对这个getKeyFromStream方法进行存根。我尝试了更明确和不太明确的(anyObject()),但似乎无论我如何尝试,此存根都不会在我的单元测试中返回fooKey。 我想知道是否是因为它受到保护,或者我缺少其他东西或做错了什么。在整个测试中,我还有其他的when / then语句在 起作用, 但是由于某种原因,事实并非如此。 注意:getKey

  • 这是我的实际服务方法。在测试时,它给我的变量为空。用户和响应 我试图写一个测试用例和模拟方法findByEmail()和保存(),但同时嘲笑我没有收到用户对象在返回中提到的thenback()和doback()。 有人能帮忙吗。

  • 我对反应性编程相对较新。我的问题是关于

  • 我是Scala新手,正在为Scala中的Play应用程序编写一些测试。Play应用程序已经用Java编写。 我有一个有一个公共方法进程的刷新服务 其中动作在另一个包中定义为POJO 我已经根据Scala指南编写了测试 当试图模拟此服务时,我使用了以下代码 我从Scala得到以下编译器错误,无法弄清楚这些类型如何是矛盾的 [错误]/home/joey/Projects/sntdb/test/cont

  • 我正在使用PowerMockito验证私有方法的调用数:。我还将该方法存根以返回预定义的值。 尽管我已将方法存根,但实际的实现正在被调用,并抛出一个,因为它的依赖项(“loader”变量,请参见下面的代码片段)没有为此测试定义(也不应该定义)。 作为实验,我把方法改成公开,然后就没问题了! 我认为这是PowerMockito中的一个错误,但我在比这更确定的事情上错了! 这是密码 为了澄清,类看起来