4

我有一个问题 mocking Calendar.getInstance()。正如你现在这个方法返回一个日历 - 我正在模拟的对象。

现在我的代码如下所示:

@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()每次它是一个新对象而不是 Calendar 的预期模拟时,都会被多次调用。

谁能看到我做错了什么?

4

3 回答 3

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 的示例也需要它。

于 2015-04-13T18:01:17.220 回答
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
   }
}
于 2013-04-22T18:10:59.353 回答
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并评估它失败的原因。

于 2013-02-14T14:53:33.247 回答