JUnit makes a new instance of the class without #BeforeEach? - java

In order to refactor testing, we are taught that JUnit will make a new instance of the class every time by doing the following:
public class someClassTest{
final private someClass obj1 = new someClass();
#Test
public void t1() {
Assertions.assertEquals(1, obj1.returnOne());
}
#Test
public void t2() {
Assertions.assertEquals(8, obj1.return(2));
}
}
Rather than using something like
#BeforeEach
void setup(){
someClass obj1 = new someClass();}
or initializing it inside the test methods every time.
My question is, why and how does my first block of code work to achieve the same purpose as the #BeforeEach?

JUnit framework manages that. It creates a new instance of the test class (someClassTest) before each test.
Take a look at this example:
public class SampleTest {
#Test
public void test1() {
System.out.println(this.toString());
}
#Test
public void test2() {
System.out.println(this.toString());
}
}
Run it and you'll see that the test class instance is different in test1 and test2, for example:
SampleTest#4e515669
SampleTest#504bae78
From that point is just an ordinary behavior of Java.
If you have a field in an object, it will be re-created (and re-initialized):
public class SampleTest {
private int i = 0;
#Test
public void test1() {
// i is 0, so lets increase and see what happens in test2
i++;
}
#Test
public void test2() {
// here i is again 0 because it was re-created, we have a different object of SampleTest
}
}

Related

How to mock method calls of some object which is passed as method parameter of method under JUnit Test

I am writing JUnit for some legacy class which I can't change. The Problem which I am facing is as follows
public class B{
public String method2() {
//fetch some data from database and return it
}
}
public class A{
public String myMethod(B b) {
return b.method2();
}
}
how can I mock the call for method2 in junit using mockito
public class B2 extends B { // so, this is, in fact, an IS-A of B
public String method2() {
return "mockedResult";
}
}
In your test, you'll now have something like this:
#Test
public void testMethod() {
A toTest = new A();
assertEquals("mockedResult", toTest.myMethod(new B2());
}
This is the very simplistic way. But I would recommend to read up on a Mocking framework, such as Mockito for more complex scenario's.
https://www.baeldung.com/mockito-series
By using Mockito, for short, it would be something like this:
public class TestClass {
#Mock
private B b;
private A toTest = new A();
#Test
public void testMethod() {
when(b.method2()).thenReturn("mockedResult");
assertEquals("mockedResult", toTest.myMethod());
}
}

How to replace method invocation with mock?

I have a class with two methods. I want to replace invocation of second method with expected result.
Here is my class under test
public class A {
public int methodOne() {
return methodTwo(1);
}
public int methodTwo(int param) {
// corresponding logic replaced for demo
throw new RuntimeException("Wrong invocation!");
}
}
And test
public class ATest {
#Test
public void test() {
final A a = spy(new A());
when(a.methodTwo(anyInt())).thenReturn(10);
a.methodOne();
verify(a, times(1)).methodTwo(anyInt());
}
}
Why I'm get an exception when start the test?
Two things that will help you here. First, from the documentation it seems you need to use the do*() api with spy() objects. Second, to call the "real" method you need to declare it specifically using doCallRealMethod()
Here's the updated test that should work for you:
public class ATest {
#Test
public void test() {
final A a = spy(new A());
doReturn(10).when(a).methodTwo(anyInt());
doCallRealMethod().when(a).methodOne();
a.methodOne();
verify(a, times(1)).methodTwo(anyInt());
}
}

In testing in java how to check if a method of an interface is called or not?

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...

JUnit test on setters and getters failing

i'm getting a nullpointerexception when i run the junit test in eclipse. what am i missing here?
MainTest
public class MainTest {
private Main main;
#Test
public void testMain() {
final Main main = new Main();
main.setStudent("James");
}
#Test
public void testGetStudent() {
assertEquals("Test getStudent ", "student", main.getStudent());
}
#Test
public void testSetStudent() {
main.setStudent("newStudent");
assertEquals("Test setStudent", "newStudent", main.getStudent());
}
}
setters and getters are in the Main class
Main
public String getStudent() {
return student;
}
public void setStudent(final String studentIn) {
this.student = studentIn;
}
thanks.
You need to initialize your main object before using it
You can do it either on an #Before method or inside the test itself.
OPTION 1
Change
#Test
public void testSetStudent() {
main.setStudent("newStudent");
assertEquals("Test setStudent", "newStudent", main.getStudent());
}
to
#Test
public void testSetStudent() {
main = new Main();
main.setStudent("newStudent");
assertEquals("Test setStudent", "newStudent", main.getStudent());
}
OPTION 2
Create a #Before method, when using #Before the main field will be created before any #Test is executed, there is another option, option 3, to use #BeforeClass
#Before
public void before(){
main = new Main();
}
OPTION 3
#BeforeClass
public static void beforeClass(){
//Here is not useful to create the main field, here is the moment to initialize
//another kind of resources.
}
Every test method gets a new instance of MainTest. This means that the changes you make in your first method won't show up in your second method, and so on. There is no sequential relationship between one test method and another.
You need to make each method a self-contained test that tests one aspect of your class's behaviour.

Junit 4, how to disable creating new instance of Test per test method

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.

Categories