Mockito - 注入嘲笑列表

fas*_*cja 14 java junit spring dependency-injection 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);
    } 
}
Run Code Online (Sandbox Code Playgroud)
@Component 
public class StrategyA implements Strategy{...}

@Component 
public class StrategyB implements Strategy{...}
Run Code Online (Sandbox Code Playgroud)

我想用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);
}
Run Code Online (Sandbox Code Playgroud)

我在线获得NullPointerException:

filter(strategy -> strategy.isApplicable(id))
Run Code Online (Sandbox Code Playgroud)

,其中声明"策略"列表已初始化但为空.有没有什么方法Mohito会像春天一样表现出来?将实现"策略"界面的所有实例自动添加到列表中?

顺便说一句我在Wrapper类中没有任何setter,如果可能的话我想以这种方式保留它.

Erw*_*ont 14

用@Spy而不是@Mock注释它.由于Mockito无法监视接口,因此请使用具体实现,例如ArrayList.在测试设置期间,将模拟添加到List间谍.这样,您无需仅为测试目的更改测试对象.

@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);
}
Run Code Online (Sandbox Code Playgroud)

  • 实际上我尝试使用 @Spy List&lt;...&gt; 但它不起作用。它必须是一个 `ArrayList&lt;...&gt;`。我认为这是因为间谍会调用列表上真正的“add”方法,该方法不会像界面中的列表那样执行任何操作。 (2认同)

tho*_*paw 7

Mockito 无法知道您想在 List策略中放入一些东西。

你应该重新考虑这个做这样的事情

@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);
}
Run Code Online (Sandbox Code Playgroud)

  • Thomas,Spring 不知何故知道......所以我想知道 Mockito 是否可以遵循相同的想法。除此之外,我不想将“setStrategies”setter 添加到 Wrapper 类。 (7认同)