英文:
Throw Exception Whenever Package Protected Static Method Is Called Using PowerMock (EasyMock)
问题
I'm trying to throw an assertion exception whenever the TimeZone.getDefaultRef()
method is called, to basically show that this method is never called during the test. The problem is that it's package protected and static, so I think I'm forced to use PowerMock. Here's my attempt:
@RunWith(PowerMockRunner.class)
@PrepareForTest(TimeZone.class)
public class RandomTestingClass {
@Before
public void setup() {
PowerMock.mockStaticPartialNice(TimeZone.class, "getDefaultRef");
PowerMock.expectPrivate(TimeZone.class,
TimeZone.class.getDeclaredMethod("getDefaultRef")).andStubThrow(new AssertionError());
PowerMock.replay(TimeZone.class);
}
@Test
public void randomTestThatShouldFailBecauseMethodCallsGetDefaultRefMethod() {
Calendar.getInstance();
}
@Test
public void randomTestThatShouldPassBecauseMethodDoesNotCallGetDefaultRefMethod() {
Calendar.getInstance(TimeZone.getTimeZone("GMT"));
}
@After
public void after() {
PowerMock.verify(TimeZone.class);
}
}
I'm getting the error java.lang.IllegalStateException: no last call on a mock available
, which I've definitely seen before but am not sure how to fix in this context. I'm also open to any other more elegant way to accomplish this. To sum up:
- Test should fail if
Timezone.getDefaultRef()
is ever called - Test shouldn't fail just because the method is never called (EasyMock is expecting the method but it never comes)
- One test failing shouldn't affect the other tests
- Everything else about the TimeZone class should operate normally
英文:
I'm trying to throw an assertion exception whenever the TimeZone.getDefaultRef() method is called, to basically show that this method is never called during the test. The problem is that it's package protected and static, so I think I'm forced to use PowerMock. Here's my attempt:
@RunWith(PowerMockRunner.class)
@PrepareForTest(TimeZone.class)
public class RandomTestingClass {
@Before
public void setup() {
PowerMock.mockStaticPartialNice(TimeZone.class, "getDefaultRef")
PowerMock.expectPrivate(TimeZone.class,
TimeZone.class.getDeclaredMethod("getDefaultRef")).andStubThrow(new AssertionError());
PowerMock.replay(TimeZone.class)
}
@Test
public void randomTestThatShouldFailBecauseMethodCallsGetDefaultRefMethod() {
Calendar.getInstance();
}
@Test
public void randomTestThatShouldPassBecauseMethodDoesNotCallGetDefaultRefMethod() {
Calendar.getInstance(TimeZone.getTimeZone("GMT"));
}
@After
public void after() {
PowerMock.verify(TimeZone.class);
{
I'm getting the error java.lang.IllegalStateException: no last call on a mock available, which I've definitely seen before but am not sure how to fix in this context. I'm also open to any other more elegant way to accomplish this. To sum up:
- Test should fail if
Timezone.getDefaultRef()
is ever called - Test shouldn't fail just because the method is never called (EasyMock is expecting the method but it never comes)
- One test failing shouldn't affect the other tests
- Everything else about the TimeZone class should operate normally
答案1
得分: 1
我正在尝试找到一种解决方法,但快速答案是该方法未被模拟。在期望过程中实际调用了真实方法。
PowerMock 无法模拟由引导类加载器加载的类。TimeZone
就是其中之一。
解决方法是模拟调用它的类。这在这里有解释。它说你需要准备调用系统类的类,而不是系统类本身。
但在你的情况下,我不确定是否可以这样做。因为你想知道是否有地方在调用你的类。所以,如果你要查找的是调用 TimeZone
的东西,那么你不能准备任何使用 TimeZone
的东西。除非你有可能调用者的有限范围。
英文:
I am trying to find a workaround but the quick answer is that the method is not mocked. The real method is called instead during the expectation.
PowerMock can't mock classes loaded by the bootstrap class loader. TimeZone
is one of those.
The solution is to mock with is calling it. It's explained here. It says you need to prepare the class calling the system class instead of the system class.
But in your case, I'm not sure you can. Because you want to know if something somewhere is calling your class. So you can't prepare whatever is using TimeZone
if that is was you are looking for. Unless you have a limited scope of possible callers.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论