user674669
user674669

Reputation: 12352

Can I mock some static methods only using powermock+mockito+junit?

I am writing a test using Junit + Mockito + Powermock.

I have a class like following which I want to test:

public class MyUtils {
    public static Object method1() {} //I want to mock this only
    public static void method2() {}   //I want to keep this as is during my test.
    public static void method3() {}   //I want to keep this as is during my test.
}

I want to mock only method1 but not method2 or method3.

@RunWith(PowerMockRunner.class)
@PrepareForTest(MyUtils.class)
public class MyTest {

    @Before
    public void setUpBeforeClass() throws Exception {
        PowerMockito.mockStatic(MyUtils.class);
    }

    @Test
    public void test1() throws Exception {
        when(MyUtils.method1()).thenReturn(something);

        MyUtils.method3(); //method3 is getting mocked with an empty implementation by PowerMockito
    }

    ...
}

Can I have some methods mocked and some not be mocked i.e. they keep their original implementation during the test? Is this possible with Mockito + Powermock?

My test may not look very elegant but I have simplified my usecase before posting here.

Thank you.

Upvotes: 3

Views: 1916

Answers (2)

Samir
Samir

Reputation: 705

Yes it is possible to mock static methods using Powermock and JUnit as below:

import static org.junit.Assert.*;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;    
import static org.powermock.api.mockito.PowerMockito.*;

@RunWith(PowerMockRunner.class)
@PrepareForTest(IDGenerator.class)
public class UserDAOTest {
@Test
public void createShouldReturnAUserId() {

    UserDAO dao = new UserDAO();

    mockStatic(IDGenerator.class);
    when(IDGenerator.generateID()).thenReturn(1);
    int result = dao.create(new User());
    assertEquals(1, result);
    verifyStatic();
}

}


public final class IDGenerator {

static int i;

public static final int generateID() {
    return i++;
}

}


public class UserDAO {

public int create(User user){
    int id = IDGenerator.generateID();
    //Save the user object to the db
    return id;

}

}



public class User {
private int id;

public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

}

Hope it helps!

Upvotes: 3

Maciej Kowalski
Maciej Kowalski

Reputation: 26522

If you have way more methods that you want to keep with real implementation than ones that need to be mocked (especially when its only one in your case) then I would go for spy instead of mock:

import static org.powermock.api.mockito.PowerMockito.spy;

@RunWith(PowerMockRunner.class)
@PrepareForTest(MyUtils.class)
public class MyTest {

    @Before
    public void setUpBeforeClass() throws Exception {
        spy(MyUtils.class);
    }

    @Test
    public void test1() throws Exception {
        doReturn(something).when(MyUtils.class, "method1");

        MyUtils.method3(); // this will be a real call
    }

    ...
}

Now all the methods except method1 will be called with real implementation.

Upvotes: 2

Related Questions