Mockito - 注入模拟列表

我有以下代码:

@Component 
public class Wrapper
{ 
    @Resource 
    private List<Strategy> strategies;

    public String getName(String id)
    {
    // the revelant part of this statement is that I would like to iterate over "strategies"
        return strategies.stream()
            .filter(strategy -> strategy.isApplicable(id))
            .findFirst().get().getAmount(id);
    } 
}

@Component 
public class StrategyA implements Strategy{...}

@Component 
public class StrategyB implements Strategy{...}

我想使用Mockito为它创建一个测试。我按如下方式编写了测试:

@InjectMocks
private Wrapper testedObject = new Wrapper ();

// I was hoping that this list will contain both strategies: strategyA and strategyB
@Mock
private List<Strategy> strategies;

@Mock
StrategyA strategyA;

@Mock
StrategyB strategyB;

@Test
public void shouldReturnNameForGivenId()
{   // irrevelant code...
    //when
    testedObject.getName(ID);
}

我正在在线获得NullPointerException:

filter(strategy -> strategy.isApplicable(id))

,其中指出“策略”列表已初始化,但为空。有什么办法让Mohito表现得和春天一样吗?自动将所有实现接口“策略”的实例添加到列表中?

顺便说一句,我在Wrappler类中没有任何二传手,如果可能的话,我想以这种方式离开它。


答案 1

用@Spy而不是@Mock对其进行注释。由于Mockito不能监视接口,因此请使用具体的实现,例如ArrayList。在测试设置期间,将模拟添加到列表间谍。这样,您就不需要仅仅为了测试目的而更改测试对象。

@InjectMocks
private Wrapper testedObject = new Wrapper();

@Spy
private ArrayList<Strategy> mockedStrategies;

@Mock
private StrategyA strategyA;

@Mock
private StrategyB strategyB;

@Before
public void setup() throws Exception {
    mockedStrategies.add(strategyA);
    mockedStrategies.add(strategyB);
}

答案 2

Mockito无法知道您想在列表策略中放入某些内容。

你应该重新思考这个问题,做这样的事情

@InjectMocks
private Wrapper testedObject = new Wrapper ();

private List<Strategy> mockedStrategies;

@Mock
StrategyA strategyA;

@Mock
StrategyB strategyB;

@Before
public void setup() throws Exception {
    mockedStrategies = Arrays.asList(strategyA, strategyB);
    wrapper.setStrategies(mockedStrategies);
}

推荐