PowerMocking static不返回预期的对象

时间:2013-01-22 10:27:56

标签: mockito powermock

我在嘲笑Calendar.getInstance()时遇到了问题。正如你现在这个方法返回一个Calendar - 我正在嘲笑的对象。

现在我的代码看起来像这样:

@RunWith(PowerMockRunner.class)
@PrepareForTest(Calendar.class)
public class SurveillanceDatabaseTest {
    @Test
    public void testFailingDatabase() throws Exception {
        mockStatic(Calendar.class);
        Calendar calendar = new GregorianCalendar();
        calendar.add(Calendar.HOUR, 1);
        when(Calendar.getInstance()).thenReturn(calendar);
        final Surveillance surveillance = new Surveillance();
        surveillance.checkDatabase();
   }
}

Calendar.getInstance()会在surveillance.checkDatabase()中被多次调用,并且每次都是新对象,而不是预期的日历模拟。

谁能看到我做错了什么?

3 个答案:

答案 0 :(得分:2)

您似乎需要在PrepareForTest标记中添加目标测试类:
@PrepareForTest({Calendar.class,Surveillance.class})

@RunWith(PowerMockRunner.class)
@PrepareForTest({ Calendar.class, Surveillance.class })
public class SurveillanceDatabaseTest {
    @Test
    public void testFailingDatabase() throws Exception {
        mockStatic(Calendar.class);
        Calendar calendar = new GregorianCalendar();
        calendar.add(Calendar.HOUR, 1);
        when(Calendar.getInstance()).thenReturn(calendar);
        final Surveillance surveillance = new Surveillance();
        surveillance.checkDatabase();
   }
}

如果我们将Surveillance类移动到MockCalendarTest类之外的某个地方,即使Tom Tresansky上面的例子也需要它。

答案 1 :(得分:0)

看起来你做的一切都是正确的。例如,下面的测试通过,证明Calendar返回的Calendar#getInstance()实际上是您使用静态模拟设置的import static org.junit.Assert.*; import static org.powermock.api.mockito.PowerMockito.*; import java.util.Calendar; import java.util.GregorianCalendar; import org.junit.Test; import org.junit.runner.RunWith; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; @RunWith(PowerMockRunner.class) @PrepareForTest(Calendar.class) public class MockCalendarTest { @Test public void testFailingDatabase() { mockStatic(Calendar.class); final Calendar testCalendar = new GregorianCalendar(); testCalendar.add(Calendar.HOUR, 1); when(Calendar.getInstance()).thenReturn(testCalendar); final Surveillance surveillance = new Surveillance(); final Calendar resultCalendar = surveillance.checkDatabase(); assertTrue(testCalendar == resultCalendar); } public static class Surveillance { public Calendar checkDatabase() { return Calendar.getInstance(); } } }

Surveillance

也许发布Calendar课程的相关部分,以便我们可以看到它是如何尝试获取新的{{1}}并评估其失败的原因。

答案 2 :(得分:0)

我对when(object.call()).andReturn(response);并不熟悉,但我认为它的工作方式与expect.(object.call()).andReturn(response);相同。如果是这种情况,那么看起来你只缺少类PowerMock.replay(Calendar.class)的重放,并且你正在尝试进行完全静态模拟而不是部分静态模拟。这应该可以解决您的问题。

@RunWith(PowerMockRunner.class)
@PrepareForTest(Calendar.class)
public class SurveillanceDatabaseTest {
    @Test
    public void testFailingDatabase() throws Exception {

        Calendar calendar = new GregorianCalendar();
        calendar.add(Calendar.HOUR, 1);

        PowerMock.mockStaticPartial(Calendar.class, "getInstance");  //Mock Static Partial
        expect(Calendar.getInstance()).andReturn(calendar);
        PowerMock.replay(Calendar.class);  // note the replay of the Class!

        final Surveillance surveillance = new Surveillance();
        surveillance.checkDatabase();

        //Whatever tests you need to do here
   }
}