0

当我在调用 Log4j.error 方法时包含一个 Throwable 时,我看到了断言错误。我在@PreparateForTest 块中有Logger.class、PrintWriter.class、AuthenticationException.class。如果我没有将 Throwable 作为参数传递,我看不到错误。

我在正确设置模拟时缺少什么?

    Caused by: java.lang.AssertionError: 
      Unexpected method call AuthenticationException.printStackTrace(java.io.PrintWriter@2c64e8ad):
            at org.junit.Assert.fail(Assert.java:93)
            at com.xxx.yy.security.client.ClientTest.authenticateFail(ClientTest.java:282)
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
            at java.lang.reflect.Method.invoke(Method.java:606)
            at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:66)
            at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:310)
            ... 23 more

JUnit 测试代码片段如下:

    AuthenticationException mockAuthException = PowerMock
                        .createMock(AuthenticationException.class);
    PrintWriter mockPrintWriter = PowerMock
                        .createMock(PrintWriter.class);
    Logger mockLogger = PowerMock.createMock(Logger.class);
    String message = "blah";
    mockLogger.error(message, mockAuthException);
    EasyMock.expectLastCall();

    mockAuthException.printStackTrace(mockPrintWriter);
    EasyMock.expectLastCall();

导致问题的代码片段如下:

    try{
    .
    .
    }catch (AuthenticationException ex) {
        LOGGER.error("SOME MESSAGE HERE", ex);
        throw ex;
    }
4

2 回答 2

1

你得到一个 Unexpected method call error可以解决如下的问题:

AuthenticationException mockAuthException = EasyMock.createNiceMock(AuthenticationException.class);
PrintWriter mockPrintWriter = EasyMock.createNiceMock(PrintWriter.class);
Logger mockLogger = EasyMock.createNiceMock(Logger.class);
String message = "blah";
mockLogger.error(message, mockAuthException);
EasyMock.expectLastCall();

mockAuthException.printStackTrace(mockPrintWriter);
EasyMock.expectLastCall();

这里的变化是使用easymock而不是powermock,并创建一个niceMock而不是普通的mock。

createMock(..)方法是严格的,无法识别一个方法是否在内部被调用,但是当你使用createNiceMock(..)这个检查时会被忽略并且你不会得到一个 UnexpectedMethodCall 错误

希望能帮助到你!

祝你好运!

于 2015-01-04T04:59:05.303 回答
0

LOGGER.error("SOME MESSAGE HERE", ex);

这一行似乎在调用 的printStacktrace方法ex,即AuthenticationException类型。由于您已经模拟了它,因此当遇到此调用时,您必须告诉对象(从技术上讲是模拟)应该表现的行为。

您有 3 个选择,除了verification通过使用来放松当然nice mocks,假设您真的希望抛出此异常(您的问题对此有点含糊):

  • 看看你是否可以期待LOGGER.error("SOME MESSAGE HERE", ex);,即模拟LOGGER. TheLOGGER似乎是一个static变量,但您似乎正在使用Powermock,所以我认为您在模拟它时不会遇到任何问题,但如果您确实担心模拟LOGGER,请继续阅读

  • 告诉Easymock它在遇到printStacktrace模拟对象上的方法调用时应该如何响应,方法是在你模拟之前像这样(作为一个方法)mockAuthException对它放置一个期望:printStacktracevoidreplay

    mockAuthException.printStacktrace(); expectLastCall().andDoSomethingIfNeeded();

  • 除非绝对必要,否则根本不要模拟AuthenticationException类型 - 它看起来确实可以不模拟它,例如,通过创建Stub类型的 a 。

于 2015-01-03T22:40:35.720 回答