【问题标题】:how to write a junit mokito test case如何编写一个junit mockito测试用例
【发布时间】:2017-08-18 07:25:06
【问题描述】:

如何编写一个Junit、Mockito 测试用例来绑定结果@Valid 功能与if-else 条件示例?

@RequestMapping(value = "/scriptfile", method = RequestMethod.POST)     
public String create(
    @Valid ScriptFile scriptFile, 
    BindingResult result, 
    ModelMap modelMap
) 
{         
    if (scriptFile == null) 
        throw new IllegalArgumentException("A scriptFile is required"); 

    if (result.hasErrors()) {                 
        modelMap.addAttribute("scriptFile", scriptFile);                     
        modelMap.addAttribute("showcases", ShowCase.findAllShowCases());                     
        return "scriptfile/create";                 
    }             
    scriptFile.persist();             
    return "redirect:/scriptfile/" + scriptFile.getId();         
}   

如何为上面的例子编写一个 Junitm Mockito 测试用例?

【问题讨论】:

    标签: java spring-mvc junit mockito


    【解决方案1】:

    会是这样的。如果可以实例化对象,则可以使用 spy 而不是 mock。或者甚至创建一个ModelMap 实例并检查属性是否设置正确而不是模拟。

    @Mock
    private BindingResult result;
    
    @Mock
    private ModelMap modelMap;
    
    @Mock 
    private ScriptFile scriptFile;
    
    @BeforeMethod
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
    }
    
    @Test(expectedExceptions = {IllegalArgumentException.class})  
    public void shouldThrowIllegalArgumentException() {
        create(null, result, modelMap);
    }
    
    @Test
    public void shouldPersistFile() {
        Mockito.when(result.hasErrors()).thenReturn(false);
        Mockito.when(scriptFile.getId()).thenReturn("FILE_ID");
    
        String output = create(scriptFile, result, modelMap);
    
        Mockito.verify(scriptFile, times(1)).persist();
        assertEquals("redirect:/scriptfile/FILE_ID", output)
    }
    
    @Test
    public void shouldHandleErrors() {
        Mockito.when(result.hasErrors()).thenReturn(true);
        Mockito.when(scriptFile.getId()).thenReturn("FILE_ID");
    
        String output = create(scriptFile, result, modelMap);
    
        Mockito.verify(modelMap, times(2)).addAttribute(Mockito.any(), Mockito.any());
        assertEquals("scriptfile/create", output)
    }
    

    【讨论】:

    • 我会:A) 在 before 方法中使用 @Mock 而不是调用 mock() 。 B) 一定要效法他的榜样。 create() 接受 3 个参数,而不是 1 个! C) 强调目标必须是 1) 测试方法的公共契约和 2) 最重要的是,测试生产类中的所有路径。最后:我想知道是否真的需要 mock ModelMap。仅当无法使用“正常”实现时才模拟对象。我希望可以简单地传入一张地图并进行相应的配置。
    • 谢谢,我只是凭记忆写的,没有用 IDE 验证它:)。我也不认为 ModelMap 应该被嘲笑,但如果没有完整的代码,我就无法判断。
    【解决方案2】:

    我会使用 mockito 来模拟 Binding 结果和 ScriptFile 类:

    @Test
    public void  create_WithErrors(){
        BindingResult bindingResult = Mockito.mock(BindingResult.class);
        BindingResult scriptFile = Mockito.mock(ScriptFile.class);
        Mockito.when(bindingResult.hasErrors()).thenReturn(true);
        String result = create(scriptFile, bindingResult, new ModelMap());
        Mockito.verify(bindingResult.hasErrors());
        Mockito.verify(scriptFile .persist(), Mockito.never());
        assertThat(result, is(equalTo("scriptfile/create")))
    }
    

    【讨论】:

      【解决方案3】:

      使用spring-test MockMvC,现有代码很多,其中之一是:

      Using Spring MVC Test to unit test multipart POST request

      而且您的代码 sn-p 不起作用,您没有绑定参数 (@RequestParam) 也代替@RequestMapping 使用@PostMapping

      【讨论】:

        【解决方案4】:

        这是一个模拟测试的例子。

        package com.ase.PRODUCTS.mockito.service;
        
        import static org.mockito.Mockito.times;
        import static org.mockito.Mockito.verify;
        import static org.mockito.Mockito.when;
        
        import org.junit.Assert;
        import org.junit.Before;
        import org.junit.Test;
        import org.mockito.InjectMocks;
        import org.mockito.Mock;
        import org.mockito.Mockito;
        import org.mockito.MockitoAnnotations;
        import org.slf4j.Logger;
        import org.slf4j.LoggerFactory;
        
        import com.ase.PRODUCTS.bean.AuthenticationStatus;
        import com.ase.PRODUCTS.bean.SignUpStatus;
        import com.ase.PRODUCTS.bean.User;
        import com.ase.PRODUCTS.dao.UserDao;
        import com.ase.PRODUCTS.repository.UserRepository;
        import com.ase.PRODUCTS.service.UserService;
        
        public class UserServiceTest {
        
            private static final Logger LOGGER = LoggerFactory.getLogger(UserServiceTest.class);
        
            @Mock
            UserRepository mockedUserRepository;
            // UserDao mockedUserDao;
        
            @InjectMocks
            UserService service;
        
            @Before
            public void setup() {
        
                MockitoAnnotations.initMocks(this);
            }
        
            @Test
            public void signUpNewUser() {
                LOGGER.info("START : Inside Unit Testing addUser() method of UserServiceTest");
                User user = new User();
                user.setEmail("kiran@gmail.com");
                LOGGER.debug("User Object :  {}", user);
                when(mockedUserRepository.findUserByEmail(user.getEmail())).thenReturn(null);
        
                SignUpStatus expectedStatus = new SignUpStatus(true, false);
                SignUpStatus actualStatus = service.addUser(user);
        
                LOGGER.debug("Expected  Output :  {}", expectedStatus);
                LOGGER.debug("Actual  Output :  {}", actualStatus);
        
                Assert.assertEquals(true, expectedStatus.equals(actualStatus));
                verify(mockedUserRepository, times(1)).save(Mockito.any(User.class));
                verify(mockedUserRepository, times(1)).findUserByEmail(user.getEmail());
        
                LOGGER.info("End : Unit Testing addUser() method of UserServiceTest");
            }
        
            @Test
            public void emailAlreadyExists() {
                LOGGER.info("START : Inside Unit Testing addUser() method of UserServiceTest");
                User user = new User();
                user.setEmail("kiran@gmail.com");
                LOGGER.debug("User Object :  {}", user);
                when(mockedUserRepository.findUserByEmail(user.getEmail())).thenReturn(user);
        
                SignUpStatus expectedStatus = new SignUpStatus(false, true);
                SignUpStatus actualStatus = service.addUser(user);
        
                LOGGER.debug("Expected  Output :  {}", expectedStatus);
                LOGGER.debug("Actual  Output :  {}", actualStatus);
        
                Assert.assertEquals(true, expectedStatus.equals(actualStatus));
                verify(mockedUserRepository, times(0)).save(Mockito.any(User.class));
                verify(mockedUserRepository, times(1)).findUserByEmail(user.getEmail());
        
                LOGGER.info("End : Unit Testing addUser() method of UserServiceTest");
            }
        
            @Test
            public void loginValidUser() {
                LOGGER.info("START : Inside Unit Testing addUser() method of UserServiceTest");
                User user = new User();
                user.setEmail("kiran@gmail.com");
                user.setPassword("123456");
                LOGGER.debug("User Object :  {}", user);
                when(mockedUserRepository.findUserByEmail(user.getEmail())).thenReturn(user);
        
                AuthenticationStatus expectedStatus = new AuthenticationStatus();
                expectedStatus.setAuthenticated(true);
                expectedStatus.setActualUser(user);
                AuthenticationStatus actualStatus = service.loginUser(user);
        
                LOGGER.debug("Expected  Output :  {}", expectedStatus);
                LOGGER.debug("Actual  Output :  {}", actualStatus);
        
                Assert.assertEquals(true, expectedStatus.equals(actualStatus));
                verify(mockedUserRepository, times(0)).save(Mockito.any(User.class));
                verify(mockedUserRepository, times(1)).findUserByEmail(user.getEmail());
        
                LOGGER.info("End : Unit Testing addUser() method of UserServiceTest");
            }
        
            @Test
            public void testLoginForInvalidEmail() {
                LOGGER.info("START : Inside Unit Testing addUser() method of UserServiceTest");
                User user = new User();
                user.setEmail("kiran@gmail.com");
                user.setPassword("123456");
                LOGGER.debug("User Object :  {}", user);
        
                AuthenticationStatus expectedStatus = new AuthenticationStatus();
                expectedStatus.setAuthenticated(false);
                expectedStatus.setActualUser(null);
        
                User actualUser = new User();
                actualUser.setEmail("kiran.com");
                actualUser.setPassword("123456");
        
                when(mockedUserRepository.findUserByEmail(user.getEmail())).thenReturn(actualUser);
        
                AuthenticationStatus actualStatus = service.loginUser(user);
        
                LOGGER.debug("Expected  Output :  {}", expectedStatus);
                LOGGER.debug("Actual  Output :  {}", actualStatus);
        
                Assert.assertEquals(true, expectedStatus.equals(actualStatus));
        
                verify(mockedUserRepository, times(1)).findUserByEmail(user.getEmail());
        
                LOGGER.info("End : Unit Testing addUser() method of UserServiceTest");
            }
        
            @Test
            public void testLoginForInvalidPassword() {
                LOGGER.info("START : Inside Unit Testing addUser() method of UserServiceTest");
                User user = new User();
                user.setEmail("kiran@gmail.com");
                user.setPassword("123456");
                LOGGER.debug("User Object :  {}", user);
        
                AuthenticationStatus expectedStatus = new AuthenticationStatus();
                expectedStatus.setAuthenticated(false);
                expectedStatus.setActualUser(null);
        
                User actualUser = new User();
                actualUser.setEmail("kiran@gmail.com");
                actualUser.setPassword("1256");
        
                when(mockedUserRepository.findUserByEmail(user.getEmail())).thenReturn(actualUser);
        
                AuthenticationStatus actualStatus = service.loginUser(user);
        
                LOGGER.debug("Expected  Output :  {}", expectedStatus);
                LOGGER.debug("Actual  Output :  {}", actualStatus);
        
                Assert.assertEquals(true, expectedStatus.equals(actualStatus));
        
                verify(mockedUserRepository, times(1)).findUserByEmail(user.getEmail());
        
                LOGGER.info("End : Unit Testing addUser() method of UserServiceTest");
            }
        
        }
        

        【讨论】:

          猜你喜欢
          • 2017-09-06
          • 1970-01-01
          • 2019-06-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-01-07
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多