JUnit #Ignore all other tests (#IgnoreOther ?) - java

I'm testing extensively with JUnit and sometimes - while debugging my code - I want (temporary) only run a single #Test of my #RunWith(Arquillian.class) test class. Currently I'm adding a #Ignore to all other tests and wondering if something like #IgnoreOther does exist.
Are there better solutions to ignore all other tests?

The simplest way is to replace all #Test to //###$$$#Test. Then when your debugging is finished replace //###$$$#Test to #Test.
Moreover typically IDEs allow running one test only. For example in Eclipse you can do it from Outline view.

Just my two cents. You can try to use Junit Rules as #srkavin suggested.
Here is an example.
package org.foo.bar;
import org.junit.rules.MethodRule;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.Statement;
public class SingleTestRule implements MethodRule {
private String applyMethod;
public SingleTestRule(String applyMethod) {
this.applyMethod = applyMethod;
}
#Override
public Statement apply(final Statement statement, final FrameworkMethod method, final Object target) {
return new Statement() {
#Override
public void evaluate() throws Throwable {
if (applyMethod.equals(method.getName())) {
statement.evaluate();
}
}
};
}
}
package org.foo.bar;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
public class IgnoreAllTest {
#Rule
public SingleTestRule test = new SingleTestRule("test1");
#Test
public void test1() throws Exception {
System.out.println("test1");
}
#Test
public void test2() throws Exception {
Assert.fail("test2");
}
#Test
public void test3() throws Exception {
Assert.fail("test3");
}
}

Test rules (JUnit 4.7+) will help. For example, you can write a rule that ignores all #Test methods except one with a specific name.

The answer from srkavin (and mijer) is correct, but the code is deprecated from JUnit 4.9. The interface and the method signature have changed. I want to provide this for others interested in this issue.
public class IgnoreOtherRule implements TestRule
{
private String applyMethod;
public IgnoreOtherRule(String applyMethod){
this.applyMethod = applyMethod;
}
#Override
public Statement apply(final Statement statement, final Description description)
{
return new Statement()
{
#Override
public void evaluate() throws Throwable {
if (applyMethod.equals(description.getMethodName())) {
statement.evaluate();
}
}
};
}
}

Related

How To Write a Java Unit Test for the Method inside Another Method?

Public Class DailyJob(){
public void runJob(ScheduleJob currentJob) {
try {
int employee = employeeService.getEmployeeNum();
JobPerformance jobPerformance = performanceService.searchJobPerformance(employee);
if(jobPerformance.size() >0 ) {
currentJob.setRecord("success");
}
else {
currentJob.setRecord("failed");
}
}
catch{
//catch error
}
}
}
By now I want to write a Junit test for runJob(). But how can I setup the value I prefer into 'employee' parameter in Junit Test while I test runJob()? Anyone know how to implement it?
You can use Mockito. You setup stubbing, which will return desired value. Also you can stub for multiple calls by
.thenReturn(9, 10, 7);
import org.junit.jupiter.api.Test;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class MyTest {
#Test
void test() {
EmployeeService employeeService = mock(EmployeeService.class);
when(employeeService.getEmployeeNum()).thenReturn(9);
}
}

public void method throws Exception if - JUNIT test: Exception should not be thrown

I have a certain public void method which throws an Exception if a condition is fulfilled.
In my case the method looks like this:
public void toBeTestedMethod(Testobject testObject) throws CertainException {
if (testObject.getStatus().getAllowsEdit()){
throw ...}
}
getStatus() is a method which returns a certain Status and getAllowsEdit() is a method which returns a boolean value and nullable = true. For the two methods there also exist set-methods.
Edit1: The test regarding this method when it fails is already running fine:
public void testToBeTestedMethod_FailureStatus() throws Exception {
try {
TestObject testObject = _testObjectMockDAO.getNewTestObject();
_testObjectMockDAO.setTestObject(testObject);
_testObjectBusinessImpl.toBeTestedMethod(testObject);
fail("Check failed");
} catch (CertainException ex) {
assertEquals(ErrorCode.WRONG_STATUS, ex.getErrorCode());
}
}
I would now like to test the method toBeTestedMethod. The target is that the method does not throw an exception but gets executed successfully.
That means I would like to write a JUNIT-test which tests the following:
public void testToBeTestedMethod_success throws Exception{
// Enter test code here
}
Edit2 (regarding the class Status):
public class Status {
...
private String _status;
public String getStatus() {
return _status;
}
}
In my opinion, I have to modify the condition in the if-statement in order to get the expected result, correct?
Note: I did not write the method and the other code. Nevertheless, my task is to test the code via JUNIT.
I tried some code, but everytime I get the error that the Excpetion was thrown.
Even if you cannot solve this problem, I would be glad to get some hints where I should look for the problem why my test does not do what I want the test to do.
Your question is very abstract and needs more data, I am posting an answer here based on what I have understood.
Here are the classes:
public class SampleTestService {
public boolean toBeTestedMethod(TestObject testObject) throws AccessViolationException {
if (testObject.getStatus().getAllowsEdit()) {
throw new AccessViolationException("Edit is allowed for this non confirmed user");
} else {
return true;
}
}
static class TestObject {
private SomeStatus someStatus;
public SomeStatus getStatus() {
return someStatus;
}
}
static class SomeStatus {
private boolean allowsEdit;
public boolean getAllowsEdit() {
return allowsEdit;
}
}
static class AccessViolationException extends RuntimeException {
public AccessViolationException(String message) {
super(message);
}
}
}
Since the method depends on another class and that class-dependent also on another class you need to mock them in the chain. Here is how I have done it:
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
#ExtendWith(SpringExtension.class)
class SampleTestServiceTest {
private final SampleTestService.TestObject mockTestObject = mock(SampleTestService.TestObject.class);
private final SampleTestService.SomeStatus mockSomeStatus = mock(SampleTestService.SomeStatus.class);
private final SampleTestService service = new SampleTestService();
#Test
void testThatMethodDoesNotThrowsException() {
when(mockTestObject.getStatus()).thenReturn(mockSomeStatus);
when(mockSomeStatus.getAllowsEdit()).thenReturn(false);
boolean result = service.toBeTestedMethod(mockTestObject);
Assertions.assertTrue(result);
}
#Test
void testThatMethodThrowsException() {
when(mockTestObject.getStatus()).thenReturn(mockSomeStatus);
when(mockSomeStatus.getAllowsEdit()).thenReturn(true);
Assertions.assertThrows(SampleTestService.AccessViolationException.class, () -> {
service.toBeTestedMethod(mockTestObject);
});
}
}

Missing method call for verify(mock) here

I have a problem with the mockito.
Code to my program
public boolean bajaContribuyente(String dni){
Contribuyente c = em.find(Contribuyente.class, dni);
if(c!=null){
em.remove(c);
return true;
}
return false;
}
And the test:
#BeforeClass
public static void setUpBeforeClass()throws Exception{
contribuyenteDAO.setEm(em);;
when(contribuyenteD.getDni()).thenReturn("4");
when(em.find(Contribuyente.class, "4")).thenReturn(contribuyenteD);
}
#Test
public void testBajaContribuyente(){
contribuyenteDAO.bajaContribuyente("4");
verify(em).find(Contribuyente.class, "4");
verify(em).remove(contribuyenteD);
}
JUnit say that missing method call for verify(mock), but i dont know why
You likely need to add a static import of Mockito's methods (e.g. verify), like the following:
import static org.mockito.Mockito.*;

PowerMock: How to unmock a method?

I have a static method that is mocked using PowerMock to throw an exception. (It deletes files.) Unfortunately, during my #After (after-each-test) method, I need to call this method without the mocks. How can I umock a method?
I don't see an equivalent to Mockito.reset(). [ Ref: mockito : how to unmock a method? ]
Example:
#RunWith(PowerMockRunner.class)
#PrepareForTest(PathUtils.class) // Important: This class has a static method we want to mock.
public class CleaningServiceImplTest2 extends TestBase {
public static final File testDirPath = new File(CleaningServiceImplTest2.class.getSimpleName());
#BeforeClass
public static void beforeAllTests() throws PathException {
recursiveDeleteDirectory(testDirPath);
}
#AfterClass
public static void afterAllTests() throws PathException {
recursiveDeleteDirectory(testDirPath);
}
private File randomParentDirPath;
private CleaningServiceImpl classUnderTest;
#Before
public void beforeEachTest() {
randomParentDirPath = new File(testDirPath, UUID.randomUUID().toString()).getAbsoluteFile();
classUnderTest = new CleaningServiceImpl(randomParentDirPath);
}
#After
public void afterEachTest() throws PathException {
recursiveDeleteDirectory(randomParentDirPath);
}
public static void recursiveDeleteDirectory(File dirPath) throws PathException {
// calls PathUtils.removeFile(...)
}
#Test
public void run_FailWhenCannotRemoveFile() throws IOException {
// We only want to mock one method. Use spy() and not mockStatic().
PowerMockito.spy(PathUtils.class);
// These two statements are tightly bound.
PowerMockito.doThrow(new PathException(PathException.PathExceptionReason.UNKNOWN, randomParentDirPath, null, "message"))
.when(PathUtils.class);
PathUtils.removeFile(Mockito.any(File.class));
classUnderTest.run();
}
}
This took me a while to figure out, so I am answering my own question.
AFAIK, you need to "undo" each mock. Mockito.reset() will not work with Class<?> references. At the end of the test method, add:
// Undo the mock above because we need to call PathUtils.removeFile() within #After.
PowerMockito.doCallRealMethod().when(PathUtils.class);
PathUtils.removeFile(Mockito.any(File.class));
The only way you can undo mocking of a static method with PowerMock is when you mock a class at the beginning of a test and then undo the mock at the end of a test. It doesn't matter if you use SPY or a regular mocking.
Tested with:
"org.powermock" % "powermock" % "1.5" % Test,
"org.powermock" % "powermock-api-mockito" % "1.6.1" % Test,
Test class
package mytests;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import static org.fest.assertions.Assertions.assertThat;
#RunWith(PowerMockRunner.class)
#PrepareForTest({StaticTest.class})
public class TestTest {
#Before
public void checkIfOriginalMethodGetsCalled() {
// PowerMockito.mockStatic(StaticTest.class); if you do this in #Before you are not going to be able to undo it
assertThat(StaticTest.staticMethod()).isEqualTo("ORIGINAL VALUE");
assertThat(StaticTest.otherStaticMethod()).isEqualTo("SPY TEST ORIGINAL");
}
#Test
public void test1() {
assertThat(StaticTest.staticMethod()).isEqualTo("ORIGINAL VALUE");
}
#Test
public void test3_mocking() {
mock(); // mock or spy static methods in a test, not in #Before
Mockito.when(StaticTest.staticMethod()).thenReturn("MOCKED VALUE");
assertThat(StaticTest.staticMethod()).isEqualTo("MOCKED VALUE");
assertThat(StaticTest.otherStaticMethod()).isEqualTo("SPY TEST ORIGINAL");
undoMock(); // undo the mock at the end of each test, not in #After
}
private void mock() {
// PowerMockito.mockStatic(StaticTest.class); both, spy and mockStatic work ok
PowerMockito.spy(StaticTest.class);
}
private void undoMock() {
PowerMockito.doCallRealMethod().when(StaticTest.class);
assertThat(StaticTest.staticMethod()).isNull(); // the undo is going to work in the next test, not here yet.
}
#Test
public void test2() {
assertThat(StaticTest.staticMethod()).isEqualTo("ORIGINAL VALUE");
}
#After
public void checkIfOriginalMethodGetsCalled_AfterMockUndo() {
// undoMock(); in #After doesn't work with static methods
assertThat(StaticTest.staticMethod()).isEqualTo("ORIGINAL VALUE");
assertThat(StaticTest.otherStaticMethod()).isEqualTo("SPY TEST ORIGINAL");
}
}
class StaticTest {
public static String staticMethod() {
return "ORIGINAL VALUE";
}
public static String otherStaticMethod() {
return "SPY TEST ORIGINAL";
}
}

Detect Failure or Error of Junit Test in #After method

Is there a way in JUnit to detect within an #After annotated method if there was a test failure or error in the test case?
One ugly solution would be something like that:
boolean withoutFailure = false;
#Test
void test() {
...
asserts...
withoutFailure = true;
}
#After
public void tearDown() {
if(!withoutFailuere) {
this.dontReuseTestenvironmentForNextTest();
}
}
This is ugly because one need to take care of the "infrastructure" (withoutFailure flag) in the test code.
I hope that there is something where I can get the test status in the #After method!?
If you are lucky enough to be using JUnit 4.9 or later, TestWatcher will do exactly what you want.
Share and Enjoy!
I extend dsaff's answer to solve the problem that a TestRule can not execute some code snipped between the execution of the test-method and the after-method. So with a simple MethodRule one can not use this rule to provide a success flag that is use in the #After annotated methods.
My idea is a hack! Anyway, it is to use a TestRule (extends TestWatcher). A TestRule will get knowledge about failed or success of a test. My TestRule will then scan the class for all Methods annotated with my new AfterHack annotations and invoke that methods with a success flag.
AfterHack annotation
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
#Retention(RUNTIME)
#Target(METHOD)
public #interface AfterHack {}
AfterHackRule
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import org.junit.rules.TestWatcher;
import org.junit.runner.Description;
public class AfterHackRule extends TestWatcher {
private Object testClassInstance;
public AfterHackRule(final Object testClassInstance) {
this.testClassInstance = testClassInstance;
}
protected void succeeded(Description description) {
invokeAfterHackMethods(true);
}
protected void failed(Throwable e, Description description) {
invokeAfterHackMethods(false);
}
public void invokeAfterHackMethods(boolean successFlag) {
for (Method afterHackMethod :
this.getAfterHackMethods(this.testClassInstance.getClass())) {
try {
afterHackMethod.invoke(this.testClassInstance, successFlag);
} catch (IllegalAccessException | IllegalArgumentException
| InvocationTargetException e) {
throw new RuntimeException("error while invoking afterHackMethod "
+ afterHackMethod);
}
}
}
private List<Method> getAfterHackMethods(Class<?> testClass) {
List<Method> results = new ArrayList<>();
for (Method method : testClass.getMethods()) {
if (method.isAnnotationPresent(AfterHack.class)) {
results.add(method);
}
}
return results;
}
}
Usage:
public class DemoTest {
#Rule
public AfterHackRule afterHackRule = new AfterHackRule(this);
#AfterHack
public void after(boolean success) {
System.out.println("afterHack:" + success);
}
#Test
public void demofails() {
Assert.fail();
}
#Test
public void demoSucceeds() {}
}
BTW:
1) Hopefully there is a better solution in Junit5
2) The better way is to use the TestWatcher Rule instead of the #Before and #After Method at all (that is the way I read dsaff's answer)
#see
I don't know any easy or elegant way to detect the failure of a Junit test in an #After method.
If it is possible to use a TestRule instead of an #After method, one possibility to do it is using two chained TestRules, using a TestWatcher as the inner rule.
Example:
package org.example;
import static org.junit.Assert.fail;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExternalResource;
import org.junit.rules.RuleChain;
import org.junit.rules.TestRule;
import org.junit.rules.TestWatcher;
import org.junit.runner.Description;
public class ExampleTest {
private String name = "";
private boolean failed;
#Rule
public TestRule afterWithFailedInformation = RuleChain
.outerRule(new ExternalResource(){
#Override
protected void after() {
System.out.println("Test "+name+" "+(failed?"failed":"finished")+".");
}
})
.around(new TestWatcher(){
#Override
protected void finished(Description description) {
name = description.getDisplayName();
}
#Override
protected void failed(Throwable e, Description description) {
failed = true;
}
})
;
#Test
public void testSomething(){
fail();
}
#Test
public void testSomethingElse(){
}
}

Categories