MyClass stays mocked between two tests - java

I have two test classes, MyFirstTest and MySecondTest. Running each independently works fine. When I run both (in eclipse select the test folder which contains these files, right click, run as junit), MySecondTest fails because MyClass is still mocked when it runs its' tests. MyFirstTest requires MyClass to be mocked. MySecondTest requires MyClass to not be mocked. I thought the tearDownMocks was suppose to 'demock' the classes.
public class MyFirstTest {
#Before
public void setUp() throws Exception {
Mockit.setUpMocks(MockMyClass.class);
}
#After
public void tearDown() throws Exception {
Mockit.tearDownMocks(MockMyClass.class);
}
#AfterClass
public static void tearDownAfterClass() throws Exception {
Mockit.tearDownMocks(MockMyClass.class);
}
#MockClass(realClass = MyClass.class, stubs = "<clinit>")
public static class MockMyClass {
...
public class MySecondTest {

The right way to do it is like mentioned below: Mock the class and assign it to a variable. And then, using that variable, you can destroy or clear the mock so that it doesn't impact any other test case.
MockUp<PmRequestData> mockpmreq = new MockUp<PmRequestData>() {
#Mock
public Map<String, KPIData> getKpiDataMap() {
return datamap;
}
};
mockpmreq.tearDown();

The Mockit.tearDownMocks() method accepts real classes and not the mocks. So, the right code would be:
Mockit.tearDownMocks(MyClass.class);

Related

How to execute a piece of code once before all test classes start?

How can I execute a method once before all tests in all classes start?
I have a program that needs a system property to be set before any test start. Is there any way to do that?
Note: #BeforeClass or #Before are used just for the same test class. In my case, I'm looking for a way to execute a method before all test classes start.
To setup precondition to your test cases you can use something like this -
#Before
public void setUp(){
// Set up you preconditions here
// This piece of code will be executed before any of the test case execute
}
if you need to run that method before the start of all test you should use the annotation #BeforeClass or if you need to execute the same method every time you will execute a test method of that class you must use #Before
f.e
#Before
public void executedBeforeEach() {
//this method will execute before every single test
}
#Test
public void EmptyCollection() {
assertTrue(testList.isEmpty());
}
You can make use of a Test Suite.
The test suite
#RunWith(Suite.class)
#Suite.SuiteClasses({ TestClass.class, Test2Class.class, })
public class TestSuite {
#BeforeClass
public static void setup() {
// the setup
}
}
and, the test classes
public class Test2Class {
#Test
public void test2() {
// some test
}
}
public class TestClass {
#Test
public void test() {
// some test
}
}
Or, you can have a base class which handles the setup
public class TestBase {
#BeforeClass
public static void setup() {
// setup
}
}
and, then the test classes can extend the base class
public class TestClass extends TestBase {
#Test
public void test() {
// some test
}
}
public class Test2Class extends TestBase {
#Test
public void test() {
// some test
}
}
However, this will call the setup method in TestBase for all its subclasses everytime each of them executes.

Why doesn't my #BeforeClass method run when executing a subclass test method?

I'm using IntelliJ IDEA CE 2018.3 and JUnit 4.12.
I have a test class that looks like this:
#RunWith(HierarchicalContextRunner.class)
public class TestClass {
#BeforeClass
public static void beforeAll() {
//start a server for all tests to hit
}
#Before
public void before() {
//init a common request object for each test
}
#Test
public void itShouldHaveSomeCommonProperty() {
//check some common thing
}
public class SomeSubTestClass {
#Before
public void before() {
//do some test case-specific setup
}
public class SomeOtherSubTestClass {
#Test
public void itShouldDoSomething() {
//hit the service and assert something about the result
}
}
}
}
When I tell IntelliJ to run the class, everything works as expected. However, if I want to just run the itShouldDoSomething test (which I'm doing by setting up a run configuration that targets the SomeOtherSubTestClass class), the beforeAll method is not executed. Both of the before methods are executed in the correct order, but not the static beforeAll method.
Am I misunderstanding something, or is this a bug?
It is not a bug.
The beforeAll method is static and therefore tied to the class and not the instance. This is why it is not executed when calling tests in inner classes or sub-classes.
To ensure it being called you would have to define a #BeforeClass method in each of your inner classes which then call the method on the outer class.

How can I control whether JUnit creates an instance of the class whose behaviour is being tested?

I have noticed that JUnit implicitly creates an instance of my test class. I have added my own call to the constructor and this does not prevent the creation of the instance by JUnit; the net result is two instances are created, as shown by the console output below.
I find this puzzling. Why is this taking place, and how can I control/prevent the creation of the instance by JUnit? A google search "junit implicit object creation" reveals nothing, but I was able to see where the constructor is invoked by debugging the test. What I don't understand is why this is taking place, when we have a place to do it ourselves, and how to prevent it from taking place. I am using JUnit 4 in eclipse photon.
Thanks.
public class MainTest extends Main {
static Main m;
#BeforeClass
public static void setUpBeforeClass() throws Exception {
System.out.println("setUpBeforeClass");
m = new Main();
}
#AfterClass
public static void tearDownAfterClass() throws Exception {
System.out.println("tearDownAfterClass");
}
#Before
public void setUp() throws Exception {
System.out.println("setup");
}
#After
public void tearDown() throws Exception {
System.out.println("tearDown");
}
#Test
public void testAdd() {
assertEquals(8,m.add(3,5));
}
}
Console output:
setUpBeforeClass
Main()
Main()
setup
tearDown
tearDownAfterClass
Your testcase extends the class Main which means the constructor is called upon creation of both the MainTest class and the explicit call of new Main()
remove the extends Main and you'll be good

How to use #BeforeClass and #AfterClass within a JerseyTest suite

It turns out that JUnit wants #BeforeClass and #AfterClass to be static and this doesn't get along well with JerseyTest's configure method override. Is there a known way to configure the Jersey application while still being able to access JUnit's utility methods?
public class MyControllerTest extends JerseyTest {
#BeforeClass
public static void setup() throws Exception {
target("myRoute").request().post(Entity.json("{}"));
}
#Override
protected Application configure() {
return new AppConfiguration();
}
}
Hence beforeClass needs to be static, target cannot be called because of its instance-method nature. While trying to use the constructor instead, it turns out that configure is run after the constructor and this prevents the setup-request to be executed and will therefor fail naturally.
Any advice is more than appreciated, thanks!
What we did in several cases to avoid heavy setups in such situations is to use a boolean flag to run that setup conditionally.
public class MyControllerTest extends JerseyTest {
private static myRouteSetupDone = false;
#Before
public void setup() throws Exception {
if (!myRouteSetupDone) {
target("myRoute").request().post(Entity.json("{}"));
myRouteSetupDone = true;
}
}
#Override
protected Application configure() {
return new AppConfiguration();
}
}
#Before does not require the static modifier and will be executed before every test-method.

Is there anything like Spring TestExecutionListener for TestSuite?

Currently for tests I'm using TestExecutionListener and it works just perfect
public class ExecutionManager extends AbstractTestExecutionListener {
#Override
public void beforeTestClass(TestContext testContext) throws Exception {
System.out.println("beforeClass");
}
#Override
public void afterTestClass(TestContext testContext) throws Exception {
System.out.println("afterClass");
}
}
Test classes:
#RunWith(SpringJUnit4ClassRunner.class)
#TestExecutionListeners(ExecutionManager.class)
public final class TC_001 {
#Test
public void test() {
System.out.println("Test_001");
}
}
#RunWith(SpringJUnit4ClassRunner.class)
#TestExecutionListeners(ExecutionManager.class)
public final class TC_002 {
#Test
public void test() {
System.out.println("Test_002");
}
}
When I include those tests in test suite, beforeTestClass(TestContext testContext) and afterTestClass(TestContext testContext) methods are executed for each test class, what is quite logical:
#RunWith(Suite.class)
#Suite.SuiteClasses({
TC_001.class,
TC_002.class
})
public final class TS_001 {
}
Is there anything like SuiteExecutionListener (TestExecutionListener for suites)?
Basically I need non-static #BeforeClass and #AfterClass for suite
OR
In ExecutionListener I need to find out what class has been launched: case or suite. For this purpose I can:
analyze StackTrace and get calling class
use Reflection.getCallerClass(int i) (which is deprecated)
pass caller class to ExecutionManager (By the way, how can I do that? Is it possible to put Object into TestContext like in Android Bundle?)
But I don't really like those solutions. SuiteExecutionListener is much more preferable
Thank you
No, there is unfortunately no such thing as a SuiteExecutionListener in the Spring TestContext Framework (TCF).
The TCF does not integrate with JUnit 4 at the suite level.
If you want to store something in the TestContext, that's not a problem. TestContext implements org.springframework.core.AttributeAccessor, so you can store attributes in the TestContext. Note, however, that the lifecycle of a given TestContext is tied to a test class.

Categories

Resources