Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mock only one static method and test the other

Tags:

java

jmockit

@Mocked Provider provider;

public static class Provider {
    public static List<Integer> getStaticList() {
        return new ArrayList<>();
    }

    public static List<Integer> test() {
        return getStaticList();
    }
}

@Test
public void testStatic() {
    ArrayList<Object> list = new ArrayList<>();
    list.add(1);

    new Expectations() {
        {
            Provider.getStaticList();
            result = list;
        }
    };

    assertThat(Provider.test(), JUnitMatchers.hasItem(1));
}

I want to mock (with JMockit) one static method that is called within another one. How can I do that? The above test fails. The real Provider.test method is never called.

like image 421
T3rm1 Avatar asked Dec 08 '15 16:12

T3rm1


2 Answers

The code below changes the behaviour of doSomething static method only, without affecting other static methods.

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;

import java.util.HashMap;
import java.util.Map;

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

@RunWith(PowerMockRunner.class)
@PrepareForTest({Foo.class})
public class Snipets {

    @Test
    public void hoge() throws Exception {
        PowerMockito.spy(Foo.class);
        PowerMockito.when(Foo.class, "doSomething").thenReturn("dummy");

        String actual = Foo.doSomething();
        assertEquals("dummy", actual);
    }

}

Foo.java

public class Foo {
    public static String doSomething() {
        return "foo";
    }
}

Source: https://gist.github.com/mid0111/8859159

like image 145
cahen Avatar answered Sep 18 '22 16:09

cahen


You can use partial mocking:

@Test
public void testStatic() {
    new Expectations(Provider.class) {{ Provider.getStaticList(); result = 1; }};

    List<Integer> test = Provider.test();

    assertTrue(test.contains(1));
}

(With no "@Mocked Provider" field for the test above.)

like image 37
Rogério Avatar answered Sep 21 '22 16:09

Rogério