Я написал тест для класса, в котором я использую Apache logger, поэтому я создал Custom Logger, как упомянуто ниже.
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;
}
}
Я использую этот регистратор в моем классе, как упоминается ниже.
private static final Logger log = Logger.getInstance(TimeZoneUtil.class);
Если в моей тестовой сборке я включаю зависимость общего типа - apache -logger-аналог, как упомянуто ниже, поэтому я не получаю никакой ошибки под названием java .lang.NoClassDefFoundError: org / apache / commons / logging / LogFactory
<fileset dir="./../thirdparty/commons-logging-1.1.1">
<include name="*.jar" />
</fileset>
Но я не хочу использовать это включение jar в моей тестовой сборке, так что есть какой-то другой подход к макету метода getInstance (), поэтому он не должен входить внутри класса logger для создания журнала или любого другого способа избавиться от этой ошибки.
В настоящее время я использую Power Mockito, как упомянуто ниже, с помощью которого я могу издеваться над классом Logger, но даже после этого я Получение ошибки.
PowerMockito.mockStatic(Logger.class);
Logger logger = mock(Logger.class);
when(Logger.getInstance(TimeZoneUtil.class)).thenReturn(logger);
when(Logger.getInstance(any(String.class))).thenReturn(logger);
Ошибка:
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)
Пожалуйста, помогите мне, предложив хороший подход, чтобы я не получал эту ошибку, это может быть насмешкой над объектом, издевающимся над мето d или любой другой подход, который может решить эту проблему, за исключением предоставления зависимости в тестовой сборке, заранее спасибо.
Включая ниже отправную точку моего класса проверенного тестового случая.
//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);
}