2015-10-23 23 views
7

私は、Springのbeanとautowiredフィールドを模倣する方法についてたくさんの記事を読んできました。しかし、私は豆のautowiredリストについては何も見つかりません。Spring Beanのautowiredリストを擬似する方法は?

コンクリート問題

私はFormValidatorManagerというクラスをしました。このクラスは、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; 
    } 
} 

このクラスをテストしたいと思います。しかし、私はvalidatorsプロパティを模擬する方法を見つけることができません。私はIFormValidatorsので

を試してみた何

は、私は彼らがFormValidatorManager.validatorsではなく、成功せずに反射することを期待してこれらのBeanの複数のインスタンスを欺くしようとした、シングルトンです。

次に、IFormValidatorsのリストを作成して、@Mockと注釈を付けました。 Listを手動で開始することによって、私はinitMocks()に作成されたリストを挿入することを望んでいました。それはまだ成功しなかった。

@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は、私が嘲笑されるだろうthougth IFormValidator.validate()にスローされます。

は、ここに私の最後の試みです。具体的な実装は呼び出さないでください。

これは、そのクラスに対する私のテストのいくつかが誤検出であり、他のテストが完全に失敗するため、実際には悪い動作につながります。

私は、特定の実装を模擬する可能性を秘めたまま、オートワウドのリストを模擬する方法を理解しようとしています。

ソリューションの開始を考えていますか?

よろしく

+0

あなたは、単一のフィールドに 'Mock' @と' Autowired' @期待どのように動作する:ここで

はfinalyソリューションですか?あなたはそれを嘲笑したいのですか、または自動配線しますか?また、あなたのテストでリストを作成し、それを検出するために春を望むことは起こりません。あなたのクラスではなく、あなたの春の設定でモックを作成し、そのための 'Mock'ファクトリメソッドを使用してください。 –

+0

私は実際にそれを嘲笑したい、しかしそれは春の豆なので、autowiredでもいけませんか?私は実際にautowiredを削除しようとしましたが、うまくいきませんでした。バリデーターがヌルであり、嘲笑されていないので、さらに悪いことです。 –

+0

上記の@Autowiredコンストラクタを使用することができます。テストでは、コンストラクタパラメータとしてバリデータをテストされたクラスに渡すことができます。 – freakman

答えて

9

私は最終的に質問をしては、あなたの問題へのより良いアプローチを与えることができ、時には...

それを考え出した:P

問題は私がバリデータをリンクしています彼らが嘲笑される前のリスト。バリデータはnullであり、MockitAnnotations.initMocks(this)の場合は参照を更新できませんでした。

また、Listのイテレータの問題を避けるために、私は@Mockの代わりに@Spyを使用しなければなりませんでした。

@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"); 
} 
関連する問題