Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 137 Vote(s) - 3.55 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to mock a autowired list of Spring beans?

#1
I've read plenty of articles about how to mock Spring's bean and their autowired fields. But there is nothing I could find about autowired lists of beans.

**Concrete problem**

I've a class called `FormValidatorManager`. This class loop through several validators which implements `IFormValidator`.

@Component
public class FormValidatorManager implements IValidatorManager {

@Autowired
private List<IFormValidator> validators;


@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;
}
}

I would like to test this class. But I can't find a way to mock `validators` property.

**What I've tried**

Since `IFormValidators` are singleton, I tried to mock several instances of these beans hoping them to be reflected in `FormValidatorManager.validators` but without success.

Then, I tried to create a list of `IFormValidators` which was annotated as `@Mock`. By initiating the `List` manually, I was hoping `initMocks()` to inject the created list. That was still without success.

Here is my last try:

@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());
}
}

An NPE is thrown in `IFormValidator.validate()` which I thougth would be mocked. The concrete implementation should not be called.

This leads to a really bad behavior since some of my tests on that class are false positives while others completly fail.

I'm trying to figure out how to mock an autowired list of beans while still having the possibility to mock specific implementations.

Do you have an idea start of solution ?

Regards
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through