I have an abstract base class, which I use as a base for my unit tests (TestNG 5.10). In this class, I initialize the whole environment for my tests, setting up database mappings, etc. This abstract class has a method with a #BeforeClass annotation which does the initialization.
Next, I extend that class with specific classes in which I have #Test methods and also #BeforeClass methods. These methods do class-specific initialization of the environment (e.g. put some records into the database).
How I can enforce a specific order of the #BeforeClass annotated methods? I need the ones from the abstract base class to be executed before the ones of the extending class.
Example:
abstract class A {
#BeforeClass
doInitialization() {...}
}
class B extends A {
#BeforeClass
doSpecificInitialization() {...}
#Test
doTests() {...}
}
Expected order:
A.doInitialization
B.doSpecificInitialization
B.doTests
Actual order:
B.doSpecificInitialization // <- crashes, as the base init is missing
(A.doInitialization // <---not executed
B.doTests) // <-/
edit: Answer below is for JUnit, but I will leave it here anyway, because it could be helpful.
According to the JUnit api: "The #BeforeClass methods of superclasses will be run before those the current class."
I tested this, and it seems to work for me.
However, as #Odys mentions below, for JUnit you need to have the two methods named differently though as doing otherwise will result in only the subclass method being run because the parent will be shadowed.
Don't put the #BeforeClass on the abstract class. Call it from each subclass.
abstract class A {
void doInitialization() {}
}
class B extends A {
#BeforeClass
void doSpecificInitialization() {
super.doInitialization();
}
#Test
void doTests() {}
}
Seems like TestNG has #BeforeClass(dependsOnMethods={"doInitialization"}) - give it a try.
I added public to the abstract class and TestNG (6.0.1) executed the doInitialization() before doTests. TestNG does not execute doInitialization() if I remove public from class A.
public abstract class A {
#BeforeClass
doInitialization() {...}
}
class B extends A {
#Test
doTests() {...}
}
I just tried your example with 5.11 and I get the #BeforeClass of the base class invoked first.
Can you post your testng.xml file? Maybe you are specifying both A and B there, while only B is necessary.
Feel free to follow up on the testng-users mailing-list and we can take a closer look at your problem.
--
Cedric
I've just gone through this and found one more way to achieve this. Just use alwaysRun on #BeforeClass or #BeforeMethod in the abstract class, works as you would expect.
public class AbstractTestClass {
#BeforeClass(alwaysRun = true)
public void generalBeforeClass() {
// do stuff
specificBeforeClass();
}
}
For JUnit:
As #fortega has mentioned:
According to the JUnit api: "The #BeforeClass methods of superclasses will be run before those the current class."
But be careful not to name both methods with the same name. Since in this case the parent method will be hidden by child parent. Source.
When I run from: JUnitCore.runClasses(TestClass.class);
It will execute the parent properly, before the child (You do not need super.SetUpBeforeClass();)
If you run it from Eclipse:
For some reason it fails to run the base class.
The work around:
Call the base class explicitely: (BaseTest.setUpBeforeClass();)
You may want to have a flag in the base class in case you run it from an application, to determine if it is already setup or not. So it only runs once if you run it via both possible methods (such as from eclipse for personal testing, and through ANT for a build release).
This appears to be a bug with Eclipse, or at least unexpected results..
How about having your #BeforeClass method call an empty specificBeforeClass() method that may or may not be overwritten by sub classes like so:
public class AbstractTestClass {
#BeforeClass
public void generalBeforeClass() {
// do stuff
specificBeforeClass();
}
protected void specificBeforeClass() {}
}
public class SpecificTest {
#Override
protected void specificBeforeClass() {
// Do specific stuff
}
// Tests
}
dependsOnMethod can be used.
e.g. in case of Spring (AbstractTestNGSpringContextTests)
#BeforeClass(alwaysRun = true, dependsOnMethods = "springTestContextPrepareTestInstance")
Check your import statement.
It should be
import org.testng.annotations.BeforeClass;
not
import org.junit.BeforeClass;
This works for me --
abstract class A {
#BeforeClass
doInitialization() {...}
}
class B extends A {
#Override
#BeforeClass
doInitialization() {
//do class specific init
}
#Test
doTests() {...}
}
Why don't you try to create an abstract method doSpecialInit() in your super class, called from your BeforeClass annotated method in superclass.
So developpers inheriting your class is forced to implement this method.
There is another easy solution here.
My particular situation is that I need to inject mock services from "BeforeClass" in the subclass before "BeforeClass" in the superclass is executed.
To do this - simply use a #ClassRule in the subclass.
For example:
#ClassRule
public static ExternalResource mocksInjector = new ExternalResource() {
#Override
protected void before() {
// inject my mock services here
// Note: this is executed before the parent class #BeforeClass
}
};
I hope this helps. This can effectively execute static setup in "reverse" order.
I've faced a similar issue today, the only difference was a Base class was not abstract
Here's my case
public class A {
#BeforeClass
private void doInitialization() {...}
}
public class B extends A {
#BeforeClass
private void doSpecificInitialization() {...}
#Test
public void doTests() {...}
}
It occurred that a #BeforeClass method from class A was never executed.
A.doInitialization() -> THIS WAS NEVER EXECUTED silently
B.doSpecificInitialization()
B.doTests()
Playing with privacy modifiers I found that TestNG will not execute a #BeforeClass annotated method from inherited class if a method is not visible from a class-inheritor
So this will work:
public class A {
#BeforeClass
private void doInitialization() {...}
}
public class B extends A {
#BeforeClass
//Here a privacy modifier matters -> please make sure your method is public or protected so it will be visible for ancestors
protected void doSpecificInitialization() {...}
#Test
public void doTests() {...}
}
As a result following happens:
A.doInitialization()
B.doSpecificInitialization()
B.doTests()
In my case (JUnit) I have the same methods called setup() in the base class and the derived class. In this case only the derived class's method is called, and I have it call the base class method.
A better and cleaner way to achieve this using inheritance may be as following -
abstract class A {
#BeforeClass
void doInitialization() {}
}
class B extends A {
#Override
#BeforeClass
void doInitialization() {
super.doInitialization();
}
#Test
void doTests() {}
}
Related
I'm using Mockito in some tests.
I have the following classes:
class BaseService {
public void save() {...}
}
public Childservice extends BaseService {
public void save(){
//some code
super.save();
}
}
I want to mock only the second call (super.save) of ChildService. The first call must call the real method. Is there a way to do that?
If you really don't have a choice for refactoring you can mock/stub everything in the super method call e.g.
class BaseService {
public void validate(){
fail(" I must not be called");
}
public void save(){
//Save method of super will still be called.
validate();
}
}
class ChildService extends BaseService{
public void load(){}
public void save(){
super.save();
load();
}
}
#Test
public void testSave() {
ChildService classToTest = Mockito.spy(new ChildService());
// Prevent/stub logic in super.save()
Mockito.doNothing().when((BaseService)classToTest).validate();
// When
classToTest.save();
// Then
verify(classToTest).load();
}
No, Mockito does not support this.
This might not be the answer you're looking for, but what you're seeing is a symptom of not applying the design principle:
Favor composition over inheritance
If you extract a strategy instead of extending a super class the problem is gone.
If however you are not allowed to change the code, but you must test it anyway, and in this awkward way, there is still hope. With some AOP tools (for example AspectJ) you can weave code into the super class method and avoid its execution entirely (yuck). This doesn't work if you're using proxies, you have to use bytecode modification (either load time weaving or compile time weaving). There are be mocking frameworks that support this type of trick as well, like PowerMock and PowerMockito.
I suggest you go for the refactoring, but if that is not an option you're in for some serious hacking fun.
Consider refactoring the code from ChildService.save() method to different method and test that new method instead of testing ChildService.save(), this way you will avoid unnecessary call to super method.
Example:
class BaseService {
public void save() {...}
}
public Childservice extends BaseService {
public void save(){
newMethod();
super.save();
}
public void newMethod(){
//some codes
}
}
I found a way to suppress the superclass method using PowerMockito. 3 simple steps need for this
Use PowerMockito.suppress method and MemberMatcher.methodsDeclaredIn method to supress parent class method
Second add Parent class in #PrepareForTest
Run your test class with PowerMock ie add #RunWith(PowerMockRunner.class) above your test class.
#RunWith(PowerMockRunner.class)
#PrepareForTest({BaseService.class})
public class TestChildService(){
#Spy
private ChildService testChildServiceObj = Mockito.spy(new ChildService());
#Test
public void testSave(){
PowerMockito.suppress(MemberMatcher.methodsDeclaredIn(BaseService.class));
//your further test code
testChildServiceObj.save();
}
}
Note: This will work only when the superclass method does not return anything.
Maybe the easiest option if inheritance makes sense is to create a new method (package private??) to call the super (lets call it superFindall), spy the real instance and then mock the superFindAll() method in the way you wanted to mock the parent class one. It's not the perfect solution in terms of coverage and visibility but it should do the job and it's easy to apply.
public Childservice extends BaseService {
public void save(){
//some code
superSave();
}
void superSave(){
super.save();
}
}
create a package protected (assumes test class in same package) method in the sub class that calls the super class method and then call that method in your overridden sub class method. you can then set expectations on this method in your test through the use of the spy pattern. not pretty but certainly better than having to deal with all the expectation setting for the super method in your test
Even if i totally agree with iwein response (
favor composition over inheritance
), i admit there are some times inheritance seems just natural, and i don't feel breaking or refactor it just for the sake of a unit test.
So, my suggestion :
/**
* BaseService is now an asbtract class encapsulating
* some common logic callable by child implementations
*/
abstract class BaseService {
protected void commonSave() {
// Put your common work here
}
abstract void save();
}
public ChildService extends BaseService {
public void save() {
// Put your child specific work here
// ...
this.commonSave();
}
}
And then, in the unit test :
ChildService childSrv = Mockito.mock(ChildService.class, Mockito.CALLS_REAL_METHODS);
Mockito.doAnswer(new Answer<Void>() {
#Override
public Boolean answer(InvocationOnMock invocation)
throws Throwable {
// Put your mocked behavior of BaseService.commonSave() here
return null;
}
}).when(childSrv).commonSave();
childSrv.save();
Mockito.verify(childSrv, Mockito.times(1)).commonSave();
// Put any other assertions to check child specific work is done
You can do this with PowerMockito and replace behavior only of the parent class method with continuing testing the child's class method. Even when the method is returning some value, lets say a string, you can do something like this:
#RunWith(PowerMockRunner.class)
#PrepareForTest({ BaseService.class })
public class TestChildService() {
private BasicService basicServiceObj;
private ChildService testee;
#Before
public void init() throws Exception {
testee = new ChildService();
basicServiceObj = PowerMockito.spy(new BaseService());
PowerMockito.doReturn("Result").when(basicServiceObj, "save", ... optionalArgs);
}
#Test
public void testSave(){
testee.save();
}
}
If you are returning nothing (void) then instead of doReturn you can use doNothing. Add some optionalArgs if the method have some arguments, if not, then skip that part.
The reason is your base class is not public-ed, then Mockito cannot intercept it due to visibility, if you change base class as public, or #Override in sub class (as public), then Mockito can mock it correctly.
public class BaseService{
public boolean foo(){
return true;
}
}
public ChildService extends BaseService{
}
#Test
#Mock ChildService childService;
public void testSave() {
Mockito.when(childService.foo()).thenReturn(false);
// When
assertFalse(childService.foo());
}
There is simple approach that works for most of cases. You can spy your object and stub the method you want to mock.
Here is an example:
MyClass myObjectSpy = Mockito.spy(myObject);
org.mockito.Mockito.doReturn("yourReturnValue").when(mySpyObject).methodToMock(any()..);
So, when you test your object, you can use myObjectSpy and when methodToMock is called, it will overwrite the normal behavior by a mock method.
This code for a method with return. In case you have a void method you can use doNothing instead.
I'm using Mockito in some tests.
I have the following classes:
class BaseService {
public void save() {...}
}
public Childservice extends BaseService {
public void save(){
//some code
super.save();
}
}
I want to mock only the second call (super.save) of ChildService. The first call must call the real method. Is there a way to do that?
If you really don't have a choice for refactoring you can mock/stub everything in the super method call e.g.
class BaseService {
public void validate(){
fail(" I must not be called");
}
public void save(){
//Save method of super will still be called.
validate();
}
}
class ChildService extends BaseService{
public void load(){}
public void save(){
super.save();
load();
}
}
#Test
public void testSave() {
ChildService classToTest = Mockito.spy(new ChildService());
// Prevent/stub logic in super.save()
Mockito.doNothing().when((BaseService)classToTest).validate();
// When
classToTest.save();
// Then
verify(classToTest).load();
}
No, Mockito does not support this.
This might not be the answer you're looking for, but what you're seeing is a symptom of not applying the design principle:
Favor composition over inheritance
If you extract a strategy instead of extending a super class the problem is gone.
If however you are not allowed to change the code, but you must test it anyway, and in this awkward way, there is still hope. With some AOP tools (for example AspectJ) you can weave code into the super class method and avoid its execution entirely (yuck). This doesn't work if you're using proxies, you have to use bytecode modification (either load time weaving or compile time weaving). There are be mocking frameworks that support this type of trick as well, like PowerMock and PowerMockito.
I suggest you go for the refactoring, but if that is not an option you're in for some serious hacking fun.
Consider refactoring the code from ChildService.save() method to different method and test that new method instead of testing ChildService.save(), this way you will avoid unnecessary call to super method.
Example:
class BaseService {
public void save() {...}
}
public Childservice extends BaseService {
public void save(){
newMethod();
super.save();
}
public void newMethod(){
//some codes
}
}
I found a way to suppress the superclass method using PowerMockito. 3 simple steps need for this
Use PowerMockito.suppress method and MemberMatcher.methodsDeclaredIn method to supress parent class method
Second add Parent class in #PrepareForTest
Run your test class with PowerMock ie add #RunWith(PowerMockRunner.class) above your test class.
#RunWith(PowerMockRunner.class)
#PrepareForTest({BaseService.class})
public class TestChildService(){
#Spy
private ChildService testChildServiceObj = Mockito.spy(new ChildService());
#Test
public void testSave(){
PowerMockito.suppress(MemberMatcher.methodsDeclaredIn(BaseService.class));
//your further test code
testChildServiceObj.save();
}
}
Note: This will work only when the superclass method does not return anything.
Maybe the easiest option if inheritance makes sense is to create a new method (package private??) to call the super (lets call it superFindall), spy the real instance and then mock the superFindAll() method in the way you wanted to mock the parent class one. It's not the perfect solution in terms of coverage and visibility but it should do the job and it's easy to apply.
public Childservice extends BaseService {
public void save(){
//some code
superSave();
}
void superSave(){
super.save();
}
}
create a package protected (assumes test class in same package) method in the sub class that calls the super class method and then call that method in your overridden sub class method. you can then set expectations on this method in your test through the use of the spy pattern. not pretty but certainly better than having to deal with all the expectation setting for the super method in your test
Even if i totally agree with iwein response (
favor composition over inheritance
), i admit there are some times inheritance seems just natural, and i don't feel breaking or refactor it just for the sake of a unit test.
So, my suggestion :
/**
* BaseService is now an asbtract class encapsulating
* some common logic callable by child implementations
*/
abstract class BaseService {
protected void commonSave() {
// Put your common work here
}
abstract void save();
}
public ChildService extends BaseService {
public void save() {
// Put your child specific work here
// ...
this.commonSave();
}
}
And then, in the unit test :
ChildService childSrv = Mockito.mock(ChildService.class, Mockito.CALLS_REAL_METHODS);
Mockito.doAnswer(new Answer<Void>() {
#Override
public Boolean answer(InvocationOnMock invocation)
throws Throwable {
// Put your mocked behavior of BaseService.commonSave() here
return null;
}
}).when(childSrv).commonSave();
childSrv.save();
Mockito.verify(childSrv, Mockito.times(1)).commonSave();
// Put any other assertions to check child specific work is done
You can do this with PowerMockito and replace behavior only of the parent class method with continuing testing the child's class method. Even when the method is returning some value, lets say a string, you can do something like this:
#RunWith(PowerMockRunner.class)
#PrepareForTest({ BaseService.class })
public class TestChildService() {
private BasicService basicServiceObj;
private ChildService testee;
#Before
public void init() throws Exception {
testee = new ChildService();
basicServiceObj = PowerMockito.spy(new BaseService());
PowerMockito.doReturn("Result").when(basicServiceObj, "save", ... optionalArgs);
}
#Test
public void testSave(){
testee.save();
}
}
If you are returning nothing (void) then instead of doReturn you can use doNothing. Add some optionalArgs if the method have some arguments, if not, then skip that part.
The reason is your base class is not public-ed, then Mockito cannot intercept it due to visibility, if you change base class as public, or #Override in sub class (as public), then Mockito can mock it correctly.
public class BaseService{
public boolean foo(){
return true;
}
}
public ChildService extends BaseService{
}
#Test
#Mock ChildService childService;
public void testSave() {
Mockito.when(childService.foo()).thenReturn(false);
// When
assertFalse(childService.foo());
}
There is simple approach that works for most of cases. You can spy your object and stub the method you want to mock.
Here is an example:
MyClass myObjectSpy = Mockito.spy(myObject);
org.mockito.Mockito.doReturn("yourReturnValue").when(mySpyObject).methodToMock(any()..);
So, when you test your object, you can use myObjectSpy and when methodToMock is called, it will overwrite the normal behavior by a mock method.
This code for a method with return. In case you have a void method you can use doNothing instead.
We have DAO tests that should run against both the real DAO/database, and against a mock dao to verify that the mock dao behaves the same as the real dao. To this end, we have a structure like this:
public abstract class DAOTestBase
{
public void testSimple()
{
// dummy assertion
assertTrue(true, "Hello");
}
}
#Test(groups = "fast")
public class TestMockDAO extends DAOTestBase
{
// setUp/tearDown and helper methods for mock
}
#Test(groups = "slow")
public class TestDAO extends DAOTestBase
{
// setUp/tearDown and helper methods for real DB
}
Unfortunately this doesn't work - TestNG doesn't think that the testSimple method is a test and hence won't run it. So instead I tried to annotate the testSimple method (or the DAOTestBase class):
A #Test annotation without any groups will lead to the same effect - the test won't run for either fast nor slow groups.
A #Test annotation with groups fast and slow will lead to the opposite effect - both TestMockDAO and TestDAO will be run regardless of whether only fast or only slow tests should be run.
A #Test annotation with a different group, say common, plus added dependsOnGroups="common" annotations in both TestMockDAO and TestDAO will also not work unless common is included in the groups to run which leads again to case 2 above (both TestMockDAO and TestDAO are run).
In the end, what I'm looking for is a way to be able to define the group for the inherited tests in the sub class, but it seems as if the #Test annotation is only applied to test methods in that very same class, not also to inherited methods that don't have a #Test annotation. Is there any other way to achieve this (without overriding all methods in the sub classes) ?
I am currently working through a similar situation.
A way to make test cases run is to use something like:
#Test
public void someTest() {
TestNG testng = new TestNG();
testng.setTestClasses(new Class[] { SomeTests.class });
testng.run();
}
Reference: http://testng.org/doc/documentation-main.html#running-testng-programmatically
Unforunately I am currently unable to get it to report the test cases within SomeTests.
Have you tried simply adding a #Test annotation on top of DAOTestBase? Each subclass will override it with its own group and this should make the method in the base a test method.
I am using TestNG 6.14.3 version and I found a solution using priority annotation.
Example:
I have a base test class:
public class TestBase {
#Test(priority = 0)
public void testA() {
assertTrue(true, "testA");
}
}
And another extended test class:
public class Test2 extends TestBase {
#Test(priority = 1)
public void testB() {
assertTrue(true, "testB");
}
}
When I run Test2 test class, I obtain the following esult:
testA: true
testB: true
I solved it this way:
The methods in the base class are in "base" group, but need to check if the test have been initialized.
public abstract DaoTestBase {
private boolean initialized = false;
#Test(groups = "base")
public void testSimple() {
if (!initialized) { return; }
// dummy assertion
assertTrue(true, "Hello");
}
}
The test is initialized in the child, in the BeforeClass annotated method.
#BeforeClass
protected void initialize() {
super.initialized = true;
}
If you annotate the parent class instead of the methods, you must pass inheritGroups=false and the group, since it inherits also the group of the base class and it will not work.
Now, you must run TestNG to check groups base,fast or base,slow. Both tests will be executed, but the one not initialized will do nothing.
It is ugly, and I would not recommend it (it looks better to redefine the methods in child and call the according super method), but in my case I need priority in my test methods, and I want to avoid that repetition in each child class.
I'm using Mockito in some tests.
I have the following classes:
class BaseService {
public void save() {...}
}
public Childservice extends BaseService {
public void save(){
//some code
super.save();
}
}
I want to mock only the second call (super.save) of ChildService. The first call must call the real method. Is there a way to do that?
If you really don't have a choice for refactoring you can mock/stub everything in the super method call e.g.
class BaseService {
public void validate(){
fail(" I must not be called");
}
public void save(){
//Save method of super will still be called.
validate();
}
}
class ChildService extends BaseService{
public void load(){}
public void save(){
super.save();
load();
}
}
#Test
public void testSave() {
ChildService classToTest = Mockito.spy(new ChildService());
// Prevent/stub logic in super.save()
Mockito.doNothing().when((BaseService)classToTest).validate();
// When
classToTest.save();
// Then
verify(classToTest).load();
}
No, Mockito does not support this.
This might not be the answer you're looking for, but what you're seeing is a symptom of not applying the design principle:
Favor composition over inheritance
If you extract a strategy instead of extending a super class the problem is gone.
If however you are not allowed to change the code, but you must test it anyway, and in this awkward way, there is still hope. With some AOP tools (for example AspectJ) you can weave code into the super class method and avoid its execution entirely (yuck). This doesn't work if you're using proxies, you have to use bytecode modification (either load time weaving or compile time weaving). There are be mocking frameworks that support this type of trick as well, like PowerMock and PowerMockito.
I suggest you go for the refactoring, but if that is not an option you're in for some serious hacking fun.
Consider refactoring the code from ChildService.save() method to different method and test that new method instead of testing ChildService.save(), this way you will avoid unnecessary call to super method.
Example:
class BaseService {
public void save() {...}
}
public Childservice extends BaseService {
public void save(){
newMethod();
super.save();
}
public void newMethod(){
//some codes
}
}
I found a way to suppress the superclass method using PowerMockito. 3 simple steps need for this
Use PowerMockito.suppress method and MemberMatcher.methodsDeclaredIn method to supress parent class method
Second add Parent class in #PrepareForTest
Run your test class with PowerMock ie add #RunWith(PowerMockRunner.class) above your test class.
#RunWith(PowerMockRunner.class)
#PrepareForTest({BaseService.class})
public class TestChildService(){
#Spy
private ChildService testChildServiceObj = Mockito.spy(new ChildService());
#Test
public void testSave(){
PowerMockito.suppress(MemberMatcher.methodsDeclaredIn(BaseService.class));
//your further test code
testChildServiceObj.save();
}
}
Note: This will work only when the superclass method does not return anything.
Maybe the easiest option if inheritance makes sense is to create a new method (package private??) to call the super (lets call it superFindall), spy the real instance and then mock the superFindAll() method in the way you wanted to mock the parent class one. It's not the perfect solution in terms of coverage and visibility but it should do the job and it's easy to apply.
public Childservice extends BaseService {
public void save(){
//some code
superSave();
}
void superSave(){
super.save();
}
}
create a package protected (assumes test class in same package) method in the sub class that calls the super class method and then call that method in your overridden sub class method. you can then set expectations on this method in your test through the use of the spy pattern. not pretty but certainly better than having to deal with all the expectation setting for the super method in your test
Even if i totally agree with iwein response (
favor composition over inheritance
), i admit there are some times inheritance seems just natural, and i don't feel breaking or refactor it just for the sake of a unit test.
So, my suggestion :
/**
* BaseService is now an asbtract class encapsulating
* some common logic callable by child implementations
*/
abstract class BaseService {
protected void commonSave() {
// Put your common work here
}
abstract void save();
}
public ChildService extends BaseService {
public void save() {
// Put your child specific work here
// ...
this.commonSave();
}
}
And then, in the unit test :
ChildService childSrv = Mockito.mock(ChildService.class, Mockito.CALLS_REAL_METHODS);
Mockito.doAnswer(new Answer<Void>() {
#Override
public Boolean answer(InvocationOnMock invocation)
throws Throwable {
// Put your mocked behavior of BaseService.commonSave() here
return null;
}
}).when(childSrv).commonSave();
childSrv.save();
Mockito.verify(childSrv, Mockito.times(1)).commonSave();
// Put any other assertions to check child specific work is done
You can do this with PowerMockito and replace behavior only of the parent class method with continuing testing the child's class method. Even when the method is returning some value, lets say a string, you can do something like this:
#RunWith(PowerMockRunner.class)
#PrepareForTest({ BaseService.class })
public class TestChildService() {
private BasicService basicServiceObj;
private ChildService testee;
#Before
public void init() throws Exception {
testee = new ChildService();
basicServiceObj = PowerMockito.spy(new BaseService());
PowerMockito.doReturn("Result").when(basicServiceObj, "save", ... optionalArgs);
}
#Test
public void testSave(){
testee.save();
}
}
If you are returning nothing (void) then instead of doReturn you can use doNothing. Add some optionalArgs if the method have some arguments, if not, then skip that part.
The reason is your base class is not public-ed, then Mockito cannot intercept it due to visibility, if you change base class as public, or #Override in sub class (as public), then Mockito can mock it correctly.
public class BaseService{
public boolean foo(){
return true;
}
}
public ChildService extends BaseService{
}
#Test
#Mock ChildService childService;
public void testSave() {
Mockito.when(childService.foo()).thenReturn(false);
// When
assertFalse(childService.foo());
}
There is simple approach that works for most of cases. You can spy your object and stub the method you want to mock.
Here is an example:
MyClass myObjectSpy = Mockito.spy(myObject);
org.mockito.Mockito.doReturn("yourReturnValue").when(mySpyObject).methodToMock(any()..);
So, when you test your object, you can use myObjectSpy and when methodToMock is called, it will overwrite the normal behavior by a mock method.
This code for a method with return. In case you have a void method you can use doNothing instead.
Let's say I have a test class called testFixtureA with several methods testA, testB, testC, etc, each with #Test annotation.
Let's now say I subclass testFixtureA into class called testFixtureAB and I don't overwrite anything. testFixtureAB is empty as for now.
When I run tests from testFixtureAB, methods testA, testB and testC are executed by test runner because test runner doesn't distinguish between test methods from class and baseclass.
How can I force test runner to leave out tests from baseclass?
and I don't overwrite anything.
testFixtureAB is empty as for now
There's your answer. If you want to not run testB from the main class, overrride it:
public class testFixtureAB extends testFixtureA {
#Override
public void testB() {}
}
Restructure your test classes.
If you don't want to use the tests from the baseclass, then don't extend it
If you need other functionality from the base class, split that class in two - the tests, and the other functionality
ignoring the whole base class:
#Ignore
class BaseClass {
// ...
}
check out this example
It's quite easy to achieve implementing some few classes:
Create your own TestRunner
Create an annotation like #IgnoreInheritedTests
Create a class that extends org.junit.runner.manipulation.Filter
On the filter class:
public class InheritedTestsFilter extends Filter {
#Override
public boolean shouldRun(Description description) {
Class<?> clazz = description.getTestClass();
String methodName = description.getMethodName();
if (clazz.isAnnotationPresent(IgnoreInheritedTests.class)) {
try {
return clazz.getDeclaredMethod(methodName) != null;
} catch (Exception e) {
return false;
}
}
return true;
}
#Override
public String describe() {
// TODO Auto-generated method stub
return null;
}
}
on your custom runner:
/**
* #param klass
* #throws InitializationError
* #since
*/
public CustomBaseRunner(Class<?> klass) throws InitializationError {
super(klass);
try {
this.filter(new InheritedTestsFilter());
} catch (NoTestsRemainException e) {
throw new IllegalStateException("class should contain at least one runnable test", e);
}
}
In Junit 5, you can make base class as abstract and extends it with a concrete class.
When you run the abstract in your IDE, your subclass will get executed instead.
In the latest JUnit you can use the #Rule annotation on the subclass to inspect the test name and intercept the test run to ignore the test dynamically. But I would suggest that #Bozho's idea is the better one - the fact that you need to do this indicates a bigger problem that probably shows inheritance is not the right solution here.
I know, it's not the answer...
Consider the reason why you extend concrete test classes. You do duplicate test methods that way.
If you share code between tests then consider writing base test classes with helper and fixture setup methods or test helper class.
If for running tests then try organizing tests with suites and categories.
What if you want to execute the same test for different configurations of the same test suite?
For example, let's say you have Class A with test1, test2 and test3 methods that hit an embedded database then you want to create separated "setUp" and "tearDown" for every embedded vendor (H2, HyperSQL, etc) but runs the same testing for each one.
I would like to extend a class that contain those test methods and configure it in a subclass. My problem is that the super class SHOULD NOT be considered as eligible for the test runner. The problem arises when the test runner executes the super class and given that don't found the corresponding setup and teardown methods, it crashs :(
In the base test class' #Test methods:
assumeTrue(getClass().equals(BaseClassTest.class));
It will ignore those in the subclass tests but not completely leave them out.
If for any reason you need two JUnit classes for same functionality, the best approach for me is:
put the common code in a parent class TestFixture with only constants and mocked services.
create two subclasses: TestFixtureA and TestFixtureB
This way you will not have duplicated code, nor double runs.
I ran into a similar issue where I had a generic abstract base class TestBase and 2 subclasses TestA, TestB that extended the base class. I wanted all tests from TestBase to run for TestA but to skip some for TestB. You can use the JUnit annotations Nested and Disabled to group tests in the base class into categories and then enable a full disable of that entire category of tests.
public class TestB extends TestBase {
// disable entire suite of inherited tests
// from the nested class declared on the parent
#Nested
#Disabled
public class ComponentCTests {}
}
public abstract class TestBase {
#Nested
public class ComponentCTests {
#Test
public void testSomething() {
// test something
}
}
}