【问题标题】:EasyMock AssertionError when invoking Logger.error(String, Throwable)调用 Logger.error(String, Throwable) 时的 EasyMock AssertionError
【发布时间】:2015-02-27 19:01:18
【问题描述】:

我在调用 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测试代码sn-p如下:

    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();

导致问题的代码 sn-p 如下:

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

【问题讨论】:

    标签: log4j easymock printstacktrace


    【解决方案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 错误

    希望对你有帮助!

    祝你好运!

    【讨论】:

      【解决方案2】:

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

      这一行似乎正在调用exprintStacktrace 方法,即AuthenticationException 类型。既然你已经模拟了它,你必须告诉对象(从技术上讲,模拟)在遇到这个调用时应该表现的行为。

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

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

      • 告诉Easymock它在遇到模拟对象mockAuthException上的printStacktrace方法调用时应该如何响应,方法是在你@之前对它设置这样的期望(printStacktracevoid方法) 987654338@模拟:

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

      • 除非绝对必要,否则不要模拟 AuthenticationException 类型 - 看起来你可以不模拟它,例如,通过创建该类型的 Stub

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-03-16
        • 2016-03-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-05-22
        • 1970-01-01
        相关资源
        最近更新 更多