如何模拟自动连接的春豆列表?

2022-09-01 15:40:16

我读过很多关于如何嘲笑Spring的豆子及其自动连接字段的文章。但是我找不到任何关于自动连接的豆子列表。

具体问题

我有一个类叫.此类循环通过几个实现 .FormValidatorManagerIFormValidator

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

我想测试这个类。但我找不到一种方法来嘲笑财产。validators

我尝试了什么

由于是单例,我试图嘲笑这些豆子的几个实例,希望它们能反映在其中,但没有成功。IFormValidatorsFormValidatorManager.validators

然后,我试图创建一个列表,其注释为.通过手动启动,我希望注入创建的列表。这仍然没有成功。IFormValidators@MockListinitMocks()

这是我最后一次尝试:

@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被扔进去,我会被嘲笑。不应要求具体执行。IFormValidator.validate()

这导致了一个非常糟糕的行为,因为我对该类的一些测试是误报,而其他测试则完全失败。

我试图弄清楚如何模拟一个自动连接的bean列表,同时仍然有可能模拟特定的实现。

你有一个想法开始解决方案吗?

问候


答案 1

我终于想通了...

有时,提出问题可以让你更好地解决问题,:p

问题是我在验证器被嘲笑之前将它们链接到列表。然后,验证程序为 null,并且在调用 时无法更新任何引用。MockitAnnotations.initMocks(this)

而且,为了避免迭代器问题,我不得不用代替。List@Spy@Mock

这是最终的解决方案:

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

答案 2

在处理多个豆类列表时添加另一个答案。Mockito对泛型一无所知,它只是使用提供的随机列表,所以在我的情况下发生了这样的事情。

enter image description here

它抛出了ClassCastException,因为豆子注入没有正确穿孔。期待 SfmcImportRepository,但注入是 SfmcParser

  @Mock SfmcEmailsCsvFileParser emailParser;
  @Mock SfmcSmsCsvFileParser smsParser;
  @Mock SfmcSmsRepository smsRepository;
  @Mock SfmcEmailRepository emailRepository;

  List<SfmcImportRepository> sfmcImportRepositories = new ArrayList<>();
  List<SfmcParser> sfmcParsers = new ArrayList<>();
  SfmcFtpService service;

  @Before
  public void init() {
    sfmcImportRepositories.add(emailRepository);
    sfmcImportRepositories.add(smsRepository);
    sfmcParsers.add(smsParser);
    sfmcParsers.add(emailParser);
    service = new SfmcFtpService(sfmcImportRepositories, sfmcParsers);
  }

推荐