Ho letto molti articoli su come deridere il bean di Spring e i loro campi autowired. Ma non c'è nulla che io possa trovare sulle liste di fagioli autowired.Come prendere in giro una lista autorizzata di bean Spring?
problema concreto
Ho una classe chiamata FormValidatorManager
. Questo ciclo di classe attraverso diversi validatori che implementa 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;
}
}
Vorrei testare questo corso. Ma non riesco a trovare un modo per deridere la proprietà validators
.
Quello che ho provato
Dal IFormValidators
sono Singleton, ho cercato di deridere diverse istanze di questi fagioli sperando loro di essere riflesse in FormValidatorManager.validators
ma senza successo.
Quindi, ho provato a creare un elenco di IFormValidators
che è stato annotato come @Mock
. Avviando manualmente il List
, speravo che initMocks()
inserisse l'elenco creato. Era ancora senza successo.
Ecco il mio ultimo tentativo:
@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());
}
}
Un NPE è gettato in IFormValidator.validate()
cui ho thougth verrebbe deriso. L'implementazione concreta non dovrebbe essere chiamata.
Questo porta a un comportamento davvero negativo poiché alcuni dei miei test su quella classe sono falsi positivi mentre altri falliscono completamente.
Sto cercando di capire come creare un elenco di bean autowired pur avendo la possibilità di simulare implementazioni specifiche.
Avete un'idea di avvio della soluzione?
saluti
Come vi aspettate '@ Mock' e' @ Autowired' sul singolo campo per lavorare? Vuoi deriderlo o cablato automaticamente? Anche la creazione di un elenco nel test e sperando in primavera di rilevarlo non accadrà mai. Crea mock nella tua configurazione di primavera invece delle tue classi, usa il metodo di produzione 'mock' di' Mockito' per quello. –
In realtà lo voglio prendere in giro, ma visto che è un fagiolo primaverile, non dovrei nemmeno essere autowired?In realtà ho provato a rimuovere l'autowired, ma non ha funzionato altrettanto bene. È anche peggio visto che i validatori sono nulli e non sono derisi. –
puoi usare @Autowired sopra il costruttore. Quindi in prova si potevano passare i validatori come parametri del costruttore alla classe testata. – freakman