简体   繁体   English

是mocking的Logger class方法解决这个错误org/apache/commons/logging/LogFactory java.lang.NoClassDefFoundError吗?

[英]Is mocking of Logger class method solution of this error org/apache/commons/logging/LogFactory java.lang.NoClassDefFoundError?

I have written a test for a class in which i am using Apache logger, So I have created a Custom Logger like mentioned below.我已经为 class 编写了一个测试,其中我正在使用 Apache 记录器,所以我创建了一个自定义记录器,如下所述。

 import java.io.Externalizable;
    import java.io.IOException;
    import java.io.ObjectInput;
    import java.io.ObjectOutput;
    import java.io.Serializable;

    import java.sql.SQLException;

    import com.medicalis.platform.InternalPlatformException;
    import com.medicalis.platform.MedicalisException;
    import com.medicalis.platform.MedicalisSQLException;
    import com.medicalis.platform.logging.windows.LogSeverity;
    import com.medicalis.platform.logging.windows.WindowsLoggingUtils;

    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;

    public class Logger implements Serializable, Externalizable {
       private Log myLogger = null;
       private String categoryName = null;
       private static final int DEFAULT_EVENT_ID = 9;
       private static final String SQL_STATE_CONSTRAINT_ERROR = "23000";

       /**
        * Creates a new Logger object.
        */
       public Logger() {
       }

       /**
        * Write objects member variables to object stream
        *
        * @param out - ObjectOutput
        *
        * @throws IOException
        */
       public void writeExternal(ObjectOutput out)
          throws IOException {
          out.writeObject(categoryName);
       }

       /**
        * Reads object stream to reconstruct object's member variables
        *
        * @param in - ObjectInput
        *
        * @throws IOException
        * @throws ClassNotFoundException
        */
       public void readExternal(ObjectInput in)
          throws IOException, ClassNotFoundException {
          this.categoryName = (String) in.readObject();
          this.myLogger = LogFactory.getLog(this.categoryName);
       }

       /**
        * Initializes log factory used for all logging.
        *
        * @param log - base logger
        * @param categoryName - String name of logger category
        */
       private Logger(Log log, String categoryName) {
          this.categoryName = categoryName;
          myLogger = log;
       }

       /**
        * Returns a Category instance for the given category name.
        *
        * @param categoryName - String name to use as the name for the log category
        *
        * @return Category logger object
        */
       public static Logger getInstance(final String categoryName) {
          Log log = LogFactory.getLog(categoryName);
          Logger logger = new Logger(log, categoryName);

          return logger;
       }

       /**
        * Returns a Category instance for the given category name.
        *
        * @param categoryClass - Object whose fully qualified classname will be used to determine the
        *        log category
        *
        * @return Category logger object
        */
       public static Logger getInstance(final Class categoryClass) {
          return getInstance(categoryClass.getName().toString());
       }

       /**
        * Logs a message at trace priority.
        *
        * @param obj object whose toString() method is used to get the message to log
        */
       public void trace(Object obj) {
          this.trace((obj == null) ? "null" : obj.toString(), null);
       }

       /**
        * Logs a message at debug priority.
        *
        * @param msg message to log
        * @param t object describing the exception or error that needs to be logged
        */
       public void trace(String msg, Throwable t) {
          myLogger.trace(msg, t);
       }

       /**
        * Logs a message at debug priority.
        *
        * @param obj object whose toString() method is used to get the message to log
        */
       public void debug(Object obj) {
          this.debug((obj == null) ? "null" : obj.toString(), null);
       }

       /**
        * Logs a message at debug priority.
        *
        * @param msg message to log
        * @param t object describing the exception or error that needs to be logged
        */
       public void debug(String msg, Throwable t) {
          myLogger.debug(msg, t);
       }

       /**
        * Logs a message at info priority.
        *
        * @param obj object whose toString() method is used to get the message to log
        */
       public void info(Object obj) {
          this.info((obj == null) ? "null" : obj.toString(), null);
       }

       /**
        * Logs a message at info priority.
        *
        * @param msg message to log
        * @param t object describing the exception or error that needs to be logged
        */
       public void info(String msg, Throwable t) {
          myLogger.info(msg, t);
       }

       /**
        * Logs a message at warn priority.
        *
        * @param obj object whose toString() method is used to get the message to log
        */
       public void warn(Object obj) {
          this.warn((obj == null) ? "null" : obj.toString(), null);
       }

       /**
        * Logs a message at warn priority.
        *
        * @param msg message to log
        * @param t object describing the exception or error that needs to be logged
        */
       public void warn(String msg, Throwable t) {
          myLogger.warn(msg, t);

          if (myLogger.isWarnEnabled()) {
             if (t instanceof MedicalisException) {
                WindowsLoggingUtils.log((MedicalisException) t, LogSeverity.WARNING);
             } else if (t == null) {
                WindowsLoggingUtils.log(msg, DEFAULT_EVENT_ID, LogSeverity.WARNING);
             }
          }
       }

       /**
        * Logs a message at error priority.
        *
        * @param obj object whose toString() method is used to get the message to log
        */
       public void error(Object obj) {
          this.error((obj == null) ? "null" : obj.toString(), null);
       }

       /**
        * Logs a message at error priority.
        *
        * @param msg message to log
        * @param t object describing the exception or error that needs to be logged
        */
       public void error(String msg, Throwable t) {
          myLogger.error(msg, t);

          if (myLogger.isErrorEnabled() && t instanceof MedicalisException) {
             if (!isSQLConstraintError(t)) {
                WindowsLoggingUtils.log((MedicalisException) t, LogSeverity.ERROR);
             }
          }
       }

       /**
        * Returns whether or not trace logging is enabled.
        *
        * @return boolean indicating if trace logging is enabled (true).
        */
       public boolean isTraceEnabled() {
          return myLogger.isTraceEnabled();
       }

       /**
        * Returns whether or not debug logging is enabled.
        *
        * @return boolean indicating if debug logging is enabled (true).
        */
       public boolean isDebugEnabled() {
          boolean isDebug = false;

          isDebug = myLogger.isDebugEnabled();

          if (!isDebug) {
             isDebug = Boolean.getBoolean("system.debug.on");
          }

          return isDebug;
       }

       /**
        * Returns whether or not info logging is enabled.
        *
        * @return boolean indicating if info logging is enabled (true).
        */
       public boolean isInfoEnabled() {
          return myLogger.isInfoEnabled();
       }

       /**
        * Returns whether or not warn logging is enabled.
        *
        * @return boolean indicating if warn logging is enabled (true).
        */
       public boolean isWarnEnabled() {
          return myLogger.isWarnEnabled();
       }

       /**
        * Returns whether or not error logging is enabled.
        *
        * @return boolean indicating if error logging is enabled (true).
        */
       public boolean isErrorEnabled() {
          return myLogger.isErrorEnabled();
       }

       /**
        * Method to determine if the error being thrown is the
        * result of a SQLConstraint Error. (This type of error may be logged
        * differently).
        *
        * @param t Throwable
        *
        * @return boolean
        */
       public boolean isSQLConstraintError(Throwable t) {
          boolean isContraintErr = false;

          Throwable cause = t;

          while (cause != null) {
             if (cause instanceof SQLException) {
                SQLException sqlCause = (SQLException) cause;

                String sqlState = sqlCause.getSQLState();

                if ((sqlState != null) && sqlState.equals(SQL_STATE_CONSTRAINT_ERROR)) {
                   isContraintErr = true;
                }

                break;
             }

             // check for infinite nesting of exceptions
             Throwable lastCause = cause;

             cause = cause.getCause();

             if (cause == lastCause) {
                break;
             }
          }

          return isContraintErr;
       }
    }

I am using this logger in my class like mentioned below.我在我的 class 中使用这个记录器,如下所述。

 private static final Logger log = Logger.getInstance(TimeZoneUtil.class);

If in my test build i am including commons-apache-logger-dependency like mentioned below so i am not getting any error called java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory如果在我的测试版本中,我包含了 commons-apache-logger-dependency,如下所述,所以我没有收到任何名为 java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory 的错误

<fileset dir="./../thirdparty/commons-logging-1.1.1">
         <include name="*.jar" />
      </fileset>

But I don't want to use this inclusion of jar in my test build so there is any other approach to mock the getInstance() menthod so it should not enter inside the logger class for creating log or any other way to get rid from this error.但是我不想在我的测试版本中使用 jar 的这种包含,因此还有任何其他方法可以模拟 getInstance() 方法,因此它不应该进入记录器 class 以创建日志或任何其他方式来摆脱这种情况错误。

currently i am using Power Mockito as mentioned below by which i am able to mock the Logger class but even after mocking it I am getting error.目前我正在使用如下所述的 Power Mockito,通过它我可以模拟 Logger class 但即使在 mocking 之后我也遇到了错误。

      PowerMockito.mockStatic(Logger.class);
      Logger logger = mock(Logger.class);
      when(Logger.getInstance(TimeZoneUtil.class)).thenReturn(logger);
      when(Logger.getInstance(any(String.class))).thenReturn(logger);

Error:错误:

Testsuite: com.medicalis.platform.timing.TimeZoneUtilTest
Tests run: 0, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.033 sec

Testcase: com.medicalis.platform.timing.TimeZoneUtilTest took 0 sec
    Caused an ERROR
org/apache/commons/logging/LogFactory
java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
    at com.medicalis.platform.logging.Logger.getInstance(Logger.java:107)
    at com.medicalis.platform.logging.Logger.getInstance(Logger.java:122)
    at com.medicalis.platform.timing.TimeZoneUtil.<clinit>(TimeZoneUtil.java:30)
    at com.medicalis.platform.timing.KnownTimeZone.loadValuesImpl(KnownTimeZone.java:51)
    at com.medicalis.platform.timing.TimeZoneUtilTest.setUp(TimeZoneUtilTest.java:69)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory
    at java.lang.ClassLoader.loadClass(ClassLoader.java:352)

Please help me by giving some good approach so i should not get this error it can be mocking of object mocking of method or any other approach which can solve this problem except providing dependency in test build thank you in advance.请通过提供一些好的方法来帮助我,所以我不应该得到这个错误它可能是 object ZD1892D85020BA22807BD0D85020BA22807BD0D8378206CC1Z 的 mocking 或任何其他可以解决此问题的方法,除非提前在测试构建中提供依赖关系。

Including below starting point of my tried testcase class.包括我尝试过的测试用例 class 的以下起点。

//import static org.easymock.EasyMock.mock;
import static org.junit.Assert.*;

import java.sql.SQLException;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import javax.sql.RowSet;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONArray;
import org.json.JSONException;
import org.junit.After;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.powermock.api.mockito.PowerMockito.*;

import static org.mockito.Matchers.*;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
//import static org.easymock.EasyMock.expect;
import com.medicalis.common.shared.UUIDHelper;
import com.medicalis.platform.logging.Logger;
import com.medicalis.platform.user.valueobject.UserData;
//import static org.powermock.api.easymock.PowerMock.mockStatic;

@RunWith(PowerMockRunner.class)
@PrepareForTest({Logger.class, LogFactory.class, TimeZoneUtil.class, KnownTimeZone.class})
public class TimeZoneUtilTest {
   public static final String UNIT_TEST_PROPERTY = "timeZoneUtilsUnitTestRunning";
   private static final String EUCLA_TZ = "Australia/Eucla";
   private static final String LA_TZ = "America/Los_Angeles";
   private static final String PERTH_TZ = "Australia/Perth";
   private static final String AUSTRALIA_PERTH_SHORT_CD = "APER";
   private static final String PERTH_TZ_JSON = "[{'timeZoneCd': 'APER', 'javaId': 'Australia/Perth', 'displayCode': 'AWST', 'timeZoneId': 12, 'windowsId': '(UTC+08:00) Perth'}]";

   private static List javaIdTestValue, timeZonesTestValue;
   private static UserData professionalUserData, rmUserData;

   /*package*/ static boolean isUnitTestRunning() {
      return String.valueOf(true).equals(System.getProperty(TimeZoneUtilTest.UNIT_TEST_PROPERTY));
   }

   @BeforeClass
   public static void setUp() throws SQLException, JSONException {

     /* mockStatic(LogFactory.class);
      Log log = mock(Log.class);
      when(LogFactory.getLog(anyString())).thenReturn(log);
   */

     mockStatic(Logger.class);
      Logger logger = mock(Logger.class);
     // expect(Logger.getInstance(TimeZoneUtil.class)).andReturn(logger);

     when(Logger.getInstance(TimeZoneUtil.class)).thenReturn(logger);
      when(Logger.getInstance(any(String.class))).thenReturn(logger);

      when(logger.isDebugEnabled()).thenReturn(Boolean.valueOf("true"));

      doNothing().when(logger).error(anyString(),any());
      doNothing().when(logger).warn(anyString(),any());

      doNothing().when(logger).debug(anyString(),any());

     doNothing().when(logger).error(anyString(),any());
      System.setProperty(UNIT_TEST_PROPERTY, String.valueOf(true));

      RowSet rowSet = new TimeZoneUtilTestRowSet();
      rowSet.next();
      rowSet.setString("javaId", EUCLA_TZ);
      javaIdTestValue = Collections.singletonList(rowSet);

      RowSet timeZoneRowSet = new TimeZoneUtilTestRowSet(new JSONArray(PERTH_TZ_JSON));
      timeZonesTestValue = Collections.singletonList(timeZoneRowSet);
      KnownTimeZone.loadValuesImpl(timeZonesTestValue);

      professionalUserData = new UserData() {
         @Override
         public boolean isProfessionalContext() {
            return true;
         }

         @Override
         public String getProfessionalTimeZoneId() {
            return LA_TZ;
         }
      };
      professionalUserData.setPreferredTimeZone(AUSTRALIA_PERTH_SHORT_CD);

      rmUserData = new UserData();
      rmUserData.setPreferredTimeZone(AUSTRALIA_PERTH_SHORT_CD);
   }

In before try to mock static method like:在尝试模拟 static 方法之前,例如:

   @Before
   public void before() throws Exception {
      mockStatic(LogFactory.class);
      Log log = mock(Log.class);
      when(LogFactory.getLog(anyString())).thenReturn(log);
      when(LogFactory.getLog(any(Class.class))).thenReturn(log);
   }

, or , 或者

   @Before
   public void before() throws Exception {
     mockStatic(Logger.class);
     Logger logger = mock(Logger.class);
     when(Logger.getInstance(any())).thenReturn(logger);
   }

you can write your test like this...你可以这样写你的测试......

public class TimeZoneUtilTest {
   public static final String UNIT_TEST_PROPERTY = "timeZoneUtilsUnitTestRunning";
   private static final String EUCLA_TZ = "Australia/Eucla";
   private static final String LA_TZ = "America/Los_Angeles";
   private static final String PERTH_TZ = "Australia/Perth";
   private static final String AUSTRALIA_PERTH_SHORT_CD = "APER";
   private static final String PERTH_TZ_JSON = "[{'timeZoneCd': 'APER', 'javaId': 'Australia/Perth', 'displayCode': 'AWST', 'timeZoneId': 12, 'windowsId': '(UTC+08:00) Perth'}]";

   private static List javaIdTestValue, timeZonesTestValue;
   private static UserData professionalUserData, rmUserData;

    @Mock
    Logger logger;
    //....
   }


暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 错误-java.lang.NoClassDefFoundError:org / apache / commons / logging / LogFactory - Error -java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory java.lang.NoClassDefFoundError:无法初始化类org.apache.commons.logging.LogFactory - java.lang.NoClassDefFoundError: Could not initialize class org.apache.commons.logging.LogFactory org.apache.http.conn.ssl上的java.lang.NoClassDefFoundError org / apache / commons / logging / LogFactory - java.lang.NoClassDefFoundError org/apache/commons/logging/LogFactory at org.apache.http.conn.ssl PDFBox / Java:打印到纸张:java.lang.NoClassDefFoundError:org / apache / commons / logging / LogFactory - PDFBox / Java: Printing to Paper:java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory 使用JasperReports API在代码中获得&#39;java.lang.NoClassDefFoundError:org / apache / commons / logging / LogFactory` - Got 'java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory` in code using JasperReports API 线程“ main”中的异常java.lang.NoClassDefFoundError:org / apache / commons / logging / LogFactory-命令行 - Exception in thread “main” java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory - Command line 线程“main”中的异常java.lang.NoClassDefFoundError:org / apache / commons / logging / LogFactory - Exception in thread “main” java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory Domino OSGi插件引发的异常java.lang.NoClassDefFoundError:org.apache.commons.logging.Logfactory - Exception Thrown java.lang.NoClassDefFoundError: org.apache.commons.logging.Logfactory from Domino OSGi Plugin 如何避免出现 java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory - How to avoid getting java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory 错误:NoClassDefFoundError:org / apache / commons / logging / LogFactory - Error: NoClassDefFoundError: org/apache/commons/logging/LogFactory
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM