如何模拟从另一个方法调用的方法

时间:2015-08-11 20:05:38

标签: java unit-testing junit powermock powermockito

我在的场景

public class SecondClass{

    SecondClass(FirstClass fc){
    ...
    }

    public void foo(String a,String b){
        ....
    }
}

public class FirstClass{
    private SecondClass sc;
    public void init(){
        sc = new SecondClass(this);
    }

    public void bar(List<Integer> input){
        .....
        sc.foo(s1,s2);
    }
}

我希望得到一个字符串参数a和b进入foo。测试类如下所示

@PrepareForTest({ FirstClass.class, SecondClass.class })
public class SampleTest
{
    private String[] texts;

    @Test
    public void testBar() throws Exception
    {
        texts = new String[2];

        final FirstClass fc = mock(FirstClass.class);
        final SecondClass sc = spy(new SecondClass(fc));

        doAnswer(invocation -> {
            texts = (String[]) invocation.getArguments();
            return null;
        }).when(sc).foo(anyString(), anyString());

        final List<Integer> input = new ArrayList<>();
        input.add(1);
        fc.bar(input);

        System.out.println(texts[0]+"<>"+text[1]);
    }
}

末尾的sysout打印null&lt;&gt; null。为什么文本数组没有得到更新?

2 个答案:

答案 0 :(得分:1)

根本问题是FirstClass初始化自己的SecondClass副本,而你想要提供模拟或类似。

反转控制依赖注入方法旨在通过为类提供操作所需的组件来缓解此类情况。您是否可以SecondClass注入FirstClass代替init()(例如通过参数FirstClass fc = new FirstClass(); fc.init(myMockedSecondClass); fc.bar(...); // now test the invocations on your mock )?这样,您可以在测试场景中提供模拟,从而测试方法调用。

e.g。

SELECT sh.CustomerID AS AccountID,
sd.SalesOrderDetailID AS TransactionID,
sh.OrderDate AS TransactionDate,
sd.LineTotal AS Amount
INTO Transactions
FROM sales.SalesOrderHeader sh INNER JOIN sales.SalesOrderDetail sd on
            sh.SalesOrderID = sd.SalesOrderID

答案 1 :(得分:1)

替换此......

public void init(){
   SecondClass sc = new SecondClass(this);
}

使用[{1}}的Setter,然后在您的测试用例中放置一个Mock,从而使您能够测试sc的真实bar方法。