J'utilise champ statique final privé LOGGER dans ma classe et je veux LOGGER.isInfoEnabled () méthode pour renvoyer false . Comment puis-je me moquer du champ final statique en utilisant mockito ou jMockit
Ma classe est:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Class1 {
private static final Logger LOGGER = LoggerFactory.getLogger(Class1.class);
public boolean demoMethod() {
System.out.println("Demo started");
if (LOGGER.isInfoEnabled()) {
System.out.println("@@@@@@@@@@@@@@ ------- info is enabled");
} else {
System.out.println("info is disabled");
}
return LOGGER.isInfoEnabled();
}
}
et son junit est:
import mockit.Mocked;
import mockit.NonStrictExpectations;
import org.mockito.InjectMocks;
import org.mockito.MockitoAnnotations;
import org.slf4j.Logger;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
import com.source.Class1;
public class MyTest {
@InjectMocks
Class1 cls1;
@BeforeMethod
public void initMocks() {
MockitoAnnotations.initMocks(this);
}
@Test
public void test(@Mocked final Logger LOGGER) {
new NonStrictExpectations() {
{
LOGGER.isInfoEnabled();
result = false;
}
};
assertFalse(cls1.demoMethod());
}
}
quand je le lance le résultat est:
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.test.MyTest
Configuring TestNG with: TestNG652Configurator
Demo started
@@@@@@@@@@@@@@ ------- info is enabled
Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 1.9 sec <<< FAILURE! - in com.test.MyTest
test(com.test.MyTest) Time elapsed: 0.168 sec <<< FAILURE!
Java.lang.AssertionError: expected [false] but found [true]
at com.test.MyTest.test(MyTest.Java:35)
Results :
Failed tests:
MyTest.test:35 expected [false] but found [true]
Tests run: 1, Failures: 1, Errors: 0, Skipped: 0
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 9.899s
[INFO] Finished at: Mon Jun 08 12:35:36 IST 2015
[INFO] Final Memory: 16M/166M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.Apache.maven.plugins:maven-surefire-plugin:2.18.1:test (default-test) on project JMockDemo: The
re are test failures.
[ERROR]
[ERROR] Please refer to D:\perfoce_code\workspace_kepler\JMockDemo\target\surefire-reports for the individual test results.
[ERROR] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.Apache.org/confluence/display/MAVEN/MojoFailureException
Je suis nouveau à jmockit et je veux que mon affaire ci-dessus se déroule avec succès . Et je dois utiliser JMockit ou mockito, je ne peux pas utiliser Powermockito . S'il vous plaît, aidez-moi.
Une méthode consiste à utiliser la réflexion pour supprimer le modificateur final
du champ, puis remplacer le champ LOGGER
par le champ Mocked
public class Class1Test {
@Test
public void test() throws Exception {
Logger logger = Mockito.mock(Logger.class);
Mockito.when(logger.isInfoEnabled()).thenReturn(false);
setFinalStatic(Class1.class.getDeclaredField("LOGGER"), logger);
Class1 cls1 = new Class1();
assertFalse(cls1.demoMethod());
}
static void setFinalStatic(Field field, Object newValue) throws Exception {
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(null, newValue);
}
}
Je pense que mockito ou jMockit ne peuvent pas se moquer des classes finales statiques alors qu'ils tentent de remplacer les méthodes lors des tests unitaires. Cependant, powerMockito peut utiliser Reflection et se moquer de la classe/des méthodes statiques finales.
Remplacer "@Mocked Logger" par "@Capturing Logger" dans le paramètre le permet.