2015-09-27 124 views
-2

如何测试春天验证我有一个春天验证:使用JUnit和的Mockito

​​

在上述验证已注入到ValidatorUtils类:

@Component 
class ValidatorUtils { 

    @Autowired 
    private PersonalIdValidator personalIdValidator; 
    private Errors errors; 
    private UserDto user; 

    void setParam(Errors errors, UserDto user) { 
     this.errors = errors; 
     this.user = user; 
    } 

    void validateAddClientAccount() { 
     validateAccount(); 
     validContributionAccount(); 
    } 

    private void validateAccount() { 
     validUsername(); 
     validPassword(); 
     validFirstName(); 
     validLastName(); 
     validPersonalId(); 
     validCity(); 
     validAddress(); 
     validEmail(); 
     validPhone(); 
    } 
    public void validateChangePassword() { 
     validChangePassword(); 
    } 

    private void validUsername() { 
     if (!user.getUsername().isEmpty()) { 
      String username = user.getUsername(); 
      if ((username.length() < 3) || (username.length() > 40)) { 
       errors.rejectValue("username", "username.format"); 
      } 
     } 
    } 

    private void validPassword() { 
     if (!user.getPassword().isEmpty()) { 
      String password = user.getPassword(); 
      if ((password.length() < 3) || (password.length() > 40)) { 
       errors.rejectValue("password", "password.format"); 
      } 
      if (!password.equals(user.getConfirmPassword())) { 
       errors.rejectValue("confirmPassword", "password.confirm"); 
      } 
     } 
    } 

    private void validFirstName() { 
     if (!user.getFirstName().isEmpty()) { 
      String firstName = user.getFirstName(); 
      String regex = "[A-ZŁ{1}]+[a-zł]+"; 
      boolean validFirstName = Pattern.matches(regex, firstName); 
      if ((firstName.length() < 3) || (firstName.length() > 40) || !validFirstName) { 
       errors.rejectValue("firstName", "firstName.format"); 
      } 
     } 
    } 

    private void validLastName() { 
     if (!user.getLastName().isEmpty()) { 
      String lastName = user.getLastName(); 
      String regex = "[A-ZĆŁŚŻŹ{1}]+[a-ząćęłńóśżź]+"; 
      String regexWithTwoLastName = "[A-ZĆŁŚŻŹ{1}]+[a-ząćęłńóśżź]++[\\s]+[A-ZĆŁŚŻŹ{1}]+[a-ząćęłńóśżź]+"; 
      boolean validLastName = Pattern.matches(regex, lastName); 
      boolean validWithTwoLastName = Pattern.matches(regexWithTwoLastName, lastName); 
      if ((lastName.length() < 3) || (lastName.length() > 40) 
        || (!validLastName && !validWithTwoLastName)) { 
       errors.rejectValue("lastName", "lastName.format"); 
      } 
     } 
    } 

这个类有更多的验证现场,但我跳过它。

我想测试我的Validator类使用Junit或最终mockito。我写这篇文章的测试类:

@RunWith(MockitoJUnitRunner.class) 
public class AddClientAccValidatorTest { 

    @InjectMocks 
    private AddClientAccountValidator validator; 
    @Mock 
    private ValidatorUtils validatoUtils; 
    private UserDto userDto; 
    public Errors errors; 

    @Before 
    public void setUp() { 
     UserDto userDto = new UserDto(); 
     errors = new BeanPropertyBindingResult(userDto, "userDto"); 
    } 

    @Test 
    public void testValidate() { 
     validator.validate(userDto, errors); 
     assertFalse(errors.hasErrors()); 
    } 

} 

但是当我运行我的测试,我得到以下Failet跟踪:

java.lang.AssertionError 
at org.junit.Assert.fail(Assert.java:86) 
at org.junit.Assert.assertTrue(Assert.java:41) 
at org.junit.Assert.assertFalse(Assert.java:64) 
at org.junit.Assert.assertFalse(Assert.java:74) 
at pl.piotr.ibank.validator.AddClientAccValidatorTest.testValidate(AddClientAccValidatorTest.java:67) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
at java.lang.reflect.Method.invoke(Unknown Source) 
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) 
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) 
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) 
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) 
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) 
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) 
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) 
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) 
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) 
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 
at org.junit.runners.ParentRunner.run(ParentRunner.java:363) 
at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37) 
at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62) 
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) 
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) 

为什么我得到这个错误?我得到这一行错误:

errors = new BeanPropertyBindingResult(userDto, "userDto"); 

而我的第二个问题是,我不能声明多个RunWith注释。当我添加:

@RunWith(MockitoJUnitRunner.class) 

使用@RunWith(Parameterized.class)

我不能参数化我的测试如何解决呢?

任何人都可以帮到我吗?也许我的做法很糟糕?用Junit测试Spring Validator的最佳方法是什么?

+0

在你测试你不加入任何行为到'ValidatorUtils validatoUtils',所以注入'AddClientAccountValidator validator'模拟将基本上无操作。另外,'UserDto userDto'将被初始化为'null',所以它肯定不会通过你定义的任何验证规则。阅读Mockito文档将是一个明显的起点。请注意,堆栈跟踪包含有用的信息:'AddClientAccValidatorTest.java:67'。请记住提及问题中的哪一行,因为它目前不明显(甚至包括在内) – kryger

+0

对不起,我粘贴错误的代码。 UserDto被初始化,并且错误行67是:'errors = new BeanPropertyBindingResult(userDto,“userDto”);' –

回答

6

无需Mockito即可成功运行测试。以下代码适用于Spring @Configuration类(弹簧测试,因为依赖项是必需的):

package foo.bar; 

import static org.junit.Assert.assertFalse; 

import org.junit.Before; 
import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.test.context.ContextConfiguration; 
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 
import org.springframework.test.context.support.AnnotationConfigContextLoader; 
import org.springframework.validation.BeanPropertyBindingResult; 
import org.springframework.validation.Errors; 

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(loader = AnnotationConfigContextLoader.class) 
public class AddClientAccValidatorTest { 

    @Configuration 
    static class ContextConfiguration { 

     @Bean 
     public AddClientAccountValidator validator() { 
      return new AddClientAccountValidator(); 
     } 

     @Bean 
     public ValidatorUtils validatorUtils() { 
      return new ValidatorUtils(); 
     } 
    } 

    @Autowired 
    private AddClientAccountValidator validator; 
    private UserDto userDto; 
    public Errors errors; 

    @Before 
    public void setUp() { 
     userDto = new UserDto(); 
     userDto.setLastName("Doe"); 
     userDto.setFirstName("John"); 
     userDto.setUsername("username"); 
     userDto.setPhone("phone"); 
     userDto.setPassword("password"); 
     userDto.setConfirmedPassword("password"); 
     userDto.setEmail("email"); 
     userDto.setContribution("contribution"); 
     userDto.setAddress("address"); 
     userDto.setCity("city"); 
     userDto.setPersonalId("personalId"); 
     errors = new BeanPropertyBindingResult(userDto, "userDto"); 
    } 

    @Test 
    public void testValidate() { 
     validator.validate(userDto, errors); 
     assertFalse(errors.hasErrors()); 
    } 
} 
+0

你也可以看看JSR-303和有关属性注释的验证。 –

+0

非常感谢。一切正常。 –

0

您不需要模拟任何东西。在验证时,我们需要我们想验证的对象和错误。创建一个包含必需字段的对象以验证错误对象。例如,

@Test 
public void shouldReturnErrorsWhenCustomObjectIsNull() { 
    CustomValidator customValidator = new CustomValidator(); 

    Employee employee = new Employee(); 
    employee.setEmployeeFirstname("empName") 


    Errors errors = new BeanPropertyBindingResult(employee, "employee"); 
    customValidator.validate(employee, errors); 
    List<ObjectError> allErrors = errors.getAllErrors(); 
    assertTrue("Errors list size should not be null : ", allErrors.size() > 0); 
    assertTrue(errors.hasErrors()); 
    assertNotNull(errors.getFieldError("empName")); 
} 
相关问题