I'm experimenting with the JUnit Enclosed runner in order to try and improve the organisation of some of my tests. At the moment I'm trying to work out how to share some setup between the inner classes.
Attempt the first:
#RunWith(Enclosed.class)
public class EnclosedTest {
#Before
public void printSomething() {
System.out.println("Helllooo Meggan");
}
public static class FirstTest {
#Test
public void assertThatSomethingIsTrue() {
assertThat(true, is(true));
}
}
public static class SecondTest {
#Test
public void assertThatSomethingIsFalse() {
assertThat(false, is(false));
}
}
}
Unfortunately, no-one says hello to Meggan. If I update an inner class to extend the outer one, then I get the following:
java.lang.Exception: class 'org.scratch.EnclosedTest$FirstTest' (possibly indirectly) contains itself as a SuiteClass
at org.junit.runners.model.InitializationError.<init>(InitializationError.java:32)
Is there a particular Enclosed idiom to use when trying to share setup between inner test classes? I was hoping it would be as simple as the C# example I found.
Enclosed runner internally works as a Suite, that is, it runs the classes as Test cases. And since Junit 4.12 abstract inner classes are ignored by Enclosed runner.
That said the way to share set up is to create an abstract class containing it (#Before, #After):
#RunWith(Enclosed.class)
public class EnclosedTest {
abstract public static class SharedSetUp {
#Before
public void printSomething() {
System.out.println("Helllooo Meggan");
}
}
public static class FirstTest extends SharedSetUp {
#Test
public void assertThatSomethingIsTrue() {
assertThat(true, is(true));
}
}
public static class SecondTest extends SharedSetUp {
#Test
public void assertThatSomethingIsFalse() {
assertThat(false, is(false));
}
}
}
Notice that you can even declare custom runners for each subclass.
Related
I have grouped my test methods in 2 Test Groups like so -
#TestGroup("integration")
public abstract static class AbstractIntegrationTest {
#ClassRule
public static TestGroupRule rule = new TestGroupRule();
}
#TestGroup("unit")
public abstract static class AbstractUnitTest {
#ClassRule
public static TestGroupRule rule = new TestGroupRule();
}
And have my test methods defined this way -
public static class UnitTest extends AbstractUnitTest {
#Test
public void Test1() {...}
#Test
public void Test2() {...}
}
public static class IntegrationTest extends AbstractIntegrationTest {
#Test
public void Test3() {...}
#Test
public void Test4() {...}
}
When I try to run one of my test methods (say Test1) from the Intellij IDE, I get an error saying -
org.junit.AssumptionViolatedException: None of the test groups [unit] are enabled. Enabled test groups: []
How can I enable my test group and if I am running a specific test, do I need to still enable anything?Have I set this up completely wrong?
Thanks.
I have TestNG tests in some classes, which extends the same main class.
I need the same last test for class1 and class2, but if I add #Test(priority = 666) to main class it start after all classes.
How I should annotate #Test in main class what would it starts after all tests of each class?
Big thanks. Also sorry for bad english.
main class
public class MainTest {
#BeforeClass()
public void setup() {
//something
}
#AfterClass()
public void tearDown() {
//something
}
#AfterMethod()
public void log_writer(Method method) {
//something
}
#Test(priority = 666) {}
}
class1
public class Class1 extends MainTest {
#Test
public void test1(){}
#Test
public void test2(){}
}
and class2
public class Class2 extends MainTest {
#Test
public void test1(){}
#Test
public void test2(){}
}
what you are looking for is the #AfterClass annotation. handle the part where you want to check logs in the AfterClass annotated method
It's not possible. Basically each #Test runs only once. If you need to do something after each test class you have to use #AfterClass annotation on method in your MainTest. You can do some hacks with method order etc. in MethodInterceptor (http://testng.org/doc/documentation-main.html#methodinterceptors) but it's not good idea for this case.
Is it possible to place the setup/teardown methods using JUnit framework in a single class (which would be my baseclass) so on test runs they methods are always called first/last? it would be in a similar way to which nunit tests can be structured
currently the only way I can get my tests to kick off is if I have the setup/teardown methods within the same class as my tests are (which is something I wan't to avoid, to keep my test classes tidy)
example I would hope to set up;
public class baseclass
{
#Before
public void setUp
{}
#After
public void tearDown
{}
}
public class tests
{
#Test
public void test1
{
// test content here
}
}
Run this test and see the sequence of events
class Test1 {
#Before
public void setUp1() {
System.out.println("setUp1");
}
}
public class Test2 extends Test1 {
#Before
public void setUp2() {
System.out.println("setUp2");
}
#Test
public void test() {
System.out.println("test");
}
}
Yes, as long as your test class extend your baseclass.
For instance:
Suite
#RunWith(Suite.class)
#SuiteClasses(Tests.class)
public class AllTests {
}
BaseClass
public class BaseClass {
#BeforeClass
public static void beforeAll() {
}
#Before
public void setUp() {
}
#After
public void tearDown {
}
#AfterClass
public static void afterAll() {
}
}
Tests
public class Test extends BaseClass {
#Test
public void test1() {
}
#Test
public void test2() {
}
}
I want to test this class which calls a method of interface using anonymous class.
public class ClassToTest
{
public void methodToTest()
{
InterefaceToMock interefaceToMockReference = new InterefaceToMock() {
#Override
public int methodToMock()
{
return 0;
}
};
interefaceToMockReference.methodToMock();
}
}
This is the interface
public interface InterefaceToMock
{
public int methodToMock();
}
I am using this approch to check it methodToMock is called or not
import static org.junit.Assert.*;
import org.junit.Test;
import mockit.FullVerificationsInOrder;
import mockit.Mocked;
import mockit.NonStrictExpectations;
public class TestAClass
{
#Mocked InterefaceToMock interefaceToMockReferenceMocked;
#Test
public void test1()
{
new NonStrictExpectations()
{
{
interefaceToMockReferenceMocked.methodToMock();times=1;
}
};
(new ClassToTest()).methodToTest();
new FullVerificationsInOrder(interefaceToMockReferenceMocked)
{
};
assertTrue(true);
}
}
But test case fails.
Can anyone help.
Your original test was almost correct. It declared the mock field as simply being #Mocked, which merely gives you a single mocked instance implementing the interface, and this is not the one used by the code under test. The JMockit API has another mocking annotation, however, which extends mocking to all implementation classes from a given base type, and by default affects all instances of said classes. So, the test should be changed as follows:
public class TestAClass
{
#Capturing InterfaceToMock anyImplementingInstance;
#Test
public void test1()
{
new ClassToTest().methodToTest();
new Verifications() {{
anyImplementingInstance.methodToMock();
}};
}
}
In the general case, if you have an class and you want to check whether a method on a Mock of that class is called, you use Mockito.verify.
For example:
public class AppTest {
#Test
public void testMe() {
final ITest iTest = Mockito.mock(ITest.class);
final CUT cut = new CUT(iTest);
cut.doStuff();
Mockito.verify(iTest).someStuff();
}
interface ITest {
void someStuff();
}
class CUT {
private final ITest iTest;
CUT(ITest iTest) {
this.iTest = iTest;
}
public void doStuff() {
iTest.someStuff();
}
}
}
Here, the test is whether ITest.someStuff() is called from CUT.doStuff().
Your example is undecipherable...
Is there some way to disable creation new instance of Test per #Test ?
One instance per test is the way JUnit works by default. You can, however, write your own test runner which uses one single instance for all tests. You'll probably want to start by extending BlockJUnit4ClassRunner.
For the sake of making this an answer:
public class MyTestClass {
private static String onceForAllTests;
#AfterClass
public static void afterClass() {
onceForAllTests = null; // silly, but just to demonstrate
}
#BeforeClass
public static void beforeClass() {
onceForAllTests = "This is set once for all tests";
}
#Test
public void sillyTest {
String someTestValue = "This is set during method";
assertNotEquals( onceForAllTests, someTestValue );
}
}
I ended up arriving independently at the solution suggested above by Mathew. I thought would post my short solution here.
The code in Kotlin:
class SingleInstanceRunner<T>(clazz : Class<T>) : BlockJUnit4ClassRunner(clazz) {
val instance : Any by lazy { super.createTest() }
override fun createTest() = instance
}
Here is the (untested) Java translation of the above:
public class SingleInstanceRunner extends BlockJUnit4ClassRunner {
private Object instance;
public SingleInstanceRunner(Class<?> clazz) throws InitializationError {
super(clazz);
}
#Override
protected synchronized Object createTest() throws Exception {
if (instance == null) {
instance = super.createTest();
}
return instance;
}
}
With this solution, annotate your test class with this runner.
In Kotlin:
#RunWith(SingleInstanceRunner::class)
class MyTest {
...
}
In Java:
#RunWith(SingleInstanceRunner.class)
public class MyTest {
...
}
This is used in combination with #FixMethodOrder to employ junit in some system test type scenarios.