2015-10-23 10 views
7

Przeczytałem wiele artykułów o tym, jak wyśmiać fasolę wiosenną i ich pola autowyred. Ale nie ma nic, co mógłbym znaleźć na temat autonored list fasoli.Jak naśmiewać się z autodired listy fasoli wiosennej?

konkretnego problemu

Mam klasy o nazwie FormValidatorManager. Ta klasa przechodzi przez kilka walidatorów, które implementują IFormValidator.

@Component 
public class FormValidatorManager implements IValidatorManager { 

    @Autowired 
    private List<IFormValidator> validators; 

    /* 
    * (non-Javadoc) 
    * 
    * @see 
    * com.sagemcom.esm.vision.business.validator.IFormValidator#validate(com 
    * .sagemcom.esm.vision.model.tablesdefinition.ColumnDTO, java.lang.String) 
    */ 
    @Override 
    public final IFieldError validate(ColumnDTO columnToValidate, String sentValue) { 
     String loweredColName = columnToValidate.getName().toLowerCase(); 
     IFieldError errorField = new FieldError(loweredColName); 

     for (IEsmFormValidator validator : validators) { 
      List<String> errrorsFound = validator.validate(columnToValidate, sentValue); 

      //les erreurs ne doivent pas être cumulées. 
      if(CollectionUtils.isNotEmpty(errrorsFound)){ 
       errorField.addErrors(errrorsFound); 
       break; 
      } 
     } 

     return errorField; 
    } 
} 

Chciałbym przetestować tę klasę. Ale nie mogę znaleźć sposobu na sfałszowanie właściwości validators.

Co Próbowałem

Od IFormValidators są Singleton, starałem się drwić kilka wystąpień tych ziaren w nadziei, żeby znaleźć odzwierciedlenie w FormValidatorManager.validators ale bez powodzenia.

Następnie próbowałem utworzyć listę IFormValidators, która została opisana jako @Mock. Przez ręczne zainicjowanie List miałem nadzieję, że initMocks() wstrzyknęło utworzoną listę. To wciąż nie było sukcesu.

Oto moja ostatnia próba:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations={"classpath:spring/test-validator-context.xml"}) 
public class FormValidatorManagerTest { 

    @Mock 
    private RegexValidator regexValidator; 

    @Mock 
    private FormNotNullValidator notNullValidator; 

    @Mock 
    private FormDataTypeValidator dataValidator; 

    @InjectMocks 
    private FormValidatorManager validatorManager; 

    @Mock 
    private List<IEsmFormValidator> validators = new ArrayList<IEsmFormValidator>(); 

    @Mock 
    private ColumnDTO columnDTO; 

    @Before 
    public void init() { 

     validators.add(notNullValidator); 
     validators.add(regexValidator); 
     validators.add(dataValidator); 

     MockitoAnnotations.initMocks(this); 

     Mockito.when(columnDTO.getTitle()).thenReturn("Mock title"); 
     Mockito.when(columnDTO.getName()).thenReturn("Mock name"); 
    } 



    @Test 
    public void testNoErrorFound(){ 
     mockValidator(notNullValidator, new ArrayList<String>()); 
     mockValidator(regexValidator, new ArrayList<String>()); 
     mockValidator(dataValidator, new ArrayList<String>()); 

     IFieldError fieldErrors = validatorManager.validate(columnDTO, "Not null value"); 

     Assert.assertEquals(0, fieldErrors.getErrors().size()); 

     verifyNumberOfValidateCalls(regexValidator, Mockito.atMost(1)); 
     verifyNumberOfValidateCalls(dataValidator, Mockito.atMost(1)); 
     verifyNumberOfValidateCalls(notNullValidator, Mockito.atMost(1)); 
    } 



    private void mockValidator(IFormValidator validator, List<String> listToReturn){ 
     Mockito.when(validator.validate(Mockito.any(ColumnDTO.class), Mockito.anyString())).thenReturn(listToReturn); 
    } 

    private void verifyNumberOfValidateCalls(IFormValidator validator, VerificationMode verifMode){ 
     Mockito.verify(validator, verifMode).validate(Mockito.any(ColumnDTO.class), Mockito.anyString()); 
    } 
} 

NPE jest wyrzucane w IFormValidator.validate() które thougth będzie wyśmiewany. Konkretnej realizacji nie należy wywoływać.

Prowadzi to do naprawdę złego zachowania, ponieważ niektóre z moich testów na tej klasie są fałszywie pozytywne, podczas gdy inne kompletnie zawodzą.

Próbuję wymyślić, jak kpić z autoprzesyłanej listy fasoli, jednocześnie mając możliwość wyśmiewania konkretnych implementacji.

Masz pomysł na początek rozwiązania?

Pozdrowienia

+0

Jak można oczekiwać '@ Mock' i' @ Autowired' na pojedyncze pole do pracy? Czy chcesz go wyśmiewać, czy też automatycznie okablować? Również tworzenie listy w teście i nadzieję, że wiosna go wykryje, nigdy się nie wydarzy. Twórz makiety w swojej wiosennej konfiguracji, zamiast w swoich klasach, użyj do tego metody '' mock' '' Mockito'. –

+0

Naprawdę chcę tego wyśmiewać, ale skoro jest to fasolka wiosenna, to czy nie powinno być również autoczerwone?Naprawdę próbowałem usunąć autowyred, ale to nie działało tak dobrze. Jest jeszcze gorzej, ponieważ walidatory są puste, a nie wyśmiewane. –

+0

możesz użyć @Autowired powyżej konstruktora. Tak więc w teście można przekazać walidatory jako parametry konstruktora do testowanej klasy. – freakman

Odpowiedz

9

I wreszcie zdobione go ...

Czasami zadaje pytanie może dać lepsze podejście do problemów: p

Problem byłem łącząc weryfikatorów do listę przed kpieniem. Walidatory były wtedy zerowe i żadne odniesienie nie mogło być aktualizowane, gdy MockitAnnotations.initMocks(this).

Co więcej, aby uniknąć problemów z iteratorem na List, musiałem użyć @Spy zamiast @Mock.

Oto wreszcie rozwiązanie:

@Mock 
private EsmRegexValidator regexValidator; 

@Mock 
private EsmFormNotNullValidator notNullValidator; 

@Mock 
private EsmFormDataTypeValidator dataValidator; 

@InjectMocks 
private EsmFormValidatorManager validatorManager; 

@Spy 
private List<IEsmFormValidator> validators = new ArrayList<IEsmFormValidator>(); 

@Mock 
private ColumnDTO columnDTO; 

@Before 
public void init() { 

    MockitoAnnotations.initMocks(this); 

    validators.add(notNullValidator); 
    validators.add(regexValidator); 
    validators.add(dataValidator); 

    Mockito.when(columnDTO.getTitle()).thenReturn("Mock title"); 
    Mockito.when(columnDTO.getName()).thenReturn("Mock name"); 
} 
Powiązane problemy