如何使用Whitebox(org.powermock.reflect)模拟私有方法

时间:2018-07-03 08:39:18

标签: java mockito junit4 powermockito white-box-testing

我想模拟另一个方法内部已调用的私有方法。

以下是我编写的示例代码。

Java代码:

package org.mockprivatemethods;

public class AccountDeposit {
    // Instantiation of AccountDetails using some DI
    AccountDetails accountDetails;
    public long deposit(long accountNum, long amountDeposited){
        long amount = 0;
        try{
        amount =  accountDetails.getAmount(accountNum);
        updateAccount(accountNum, amountDeposited);
        amount= amount + amountDeposited;
        } catch(Exception e){
            // log exception
        }
        return amount;
    }

    private void updateAccount(long accountNum, long amountDeposited) throws Exception {
        // some database operation to update amount in the account      
    }

    // for testing private methods 
    private int sum(int num1, int num2){
        return num1+num2;
    }
}

class AccountDetails{

    public long getAmount(long accountNum) throws Exception{
        // some database operation returning amount in the account
        long amount = 10000L;
        return amount;
    }
}

测试类:

package org.mockprivatemethods;

import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.reflect.Whitebox;

@RunWith(PowerMockRunner.class)
public class TestAccountDeposit {

    @InjectMocks
    AccountDeposit accountDeposit;

    @Mock
    AccountDetails accountDetailsMocks;

    @Test
    public void testDposit() throws Exception{
        long amount = 200;
        when(accountDetailsMocks.getAmount(Mockito.anyLong()))
            .thenReturn(amount);
        // need to mock private method updateAccount
        // just like we tested the private method "sum()" using Whitebox
        // How to mock this private method updateAccount
        long totalAmount = accountDeposit.deposit(12345678L, 50);
        assertTrue("Amount in Account(200+50): "+totalAmount , 250==totalAmount);
    }

    @Test
    public void testSum(){
        try {
            int amount = Whitebox.invokeMethod(accountDeposit, "sum", 20, 30);
            assertTrue("Sum of (20,30): "+amount, 50==amount);
        } catch (Exception e) {
            Assert.fail("testSum() failed with following error: "+e);
        }

    }
}

我们可以使用Whitebox.invokeMethod()测试私有方法。我的问题是:有什么办法可以使用Whitebox模拟私有方法。我们是否可以编写类似于下面的代码来模拟updateAccount(),因为我不希望在测试Deposit()方法时执行任何数据库操作?

when(accountDetailsMocks.getAmount(Mockito.anyLong()))
                .thenReturn(amount);

感谢您的帮助!谢谢!

0 个答案:

没有答案