title: How to mock a autowired list of Spring beans?
body: <p>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.</p>
  
  <p><strong>Concrete problem</strong></p>
  
  <p>I've a class called <code>FormValidatorManager</code>. This class loop through several validators which implements <code>IFormValidator</code>. </p>
  
  <pre><code>@Component
  public class FormValidatorManager implements IValidatorManager {
  
      @Autowired
      private List&lt;IFormValidator&gt; 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&lt;String&gt; errrorsFound = validator.validate(columnToValidate, sentValue);
  
              //les erreurs ne doivent pas être cumulées.
              if(CollectionUtils.isNotEmpty(errrorsFound)){
                  errorField.addErrors(errrorsFound);
                  break;
              }
          }
  
          return errorField;
      }
  }
  </code></pre>
  
  <p>I would like to test this class. But I can't find a way to mock <code>validators</code> property.</p>
  
  <p><strong>What I've tried</strong></p>
  
  <p>Since <code>IFormValidators</code> are singleton, I tried to mock several instances of these beans hoping them to be reflected in <code>FormValidatorManager.validators</code> but without success.</p>
  
  <p>Then, I tried to create a list of <code>IFormValidators</code> which was annotated as  <code>@Mock</code>. By initiating the <code>List</code> manually, I was hoping <code>initMocks()</code> to inject the created list. That was still without success.</p>
  
  <p>Here is my last try:</p>
  
  <pre><code>@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&lt;IEsmFormValidator&gt; validators = new ArrayList&lt;IEsmFormValidator&gt;();
  
      @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&lt;String&gt;());
          mockValidator(regexValidator,  new ArrayList&lt;String&gt;());
          mockValidator(dataValidator,  new ArrayList&lt;String&gt;());
  
          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&lt;String&gt; 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());
      }
  }
  </code></pre>
  
  <p>An NPE is thrown in <code>IFormValidator.validate()</code> which I thougth would be mocked. The concrete implementation should not be called.</p>
  
  <p>This leads to a really bad behavior since some of my tests on that class are false positives while others completly fail.</p>
  
  <p>I'm trying to figure out how to mock an autowired list of beans while still having the possibility to mock specific implementations.</p>
  
  <p>Do you have an idea start of solution ?</p>
  
  <p>Regards</p>