How does this code work for JUnit in JAVA? - java

I have the following code for JUnit testing:
import static org.junit.Assert.assertEquals;
import org.junit.Before;
import org.junit.Test;
public class JUnitHelloWorld {
protected String s;
#Before
public void setup() {
s = "HELLO WORLD";
}
#Test
public void testHelloWorldSuccess() {
s = s.toLowerCase();
assertEquals("hello world", s);
}
// will fail even if testHelloWorldSuccess is called first
#Test
public void testHelloWorldFail() {
assertEquals("hello world", s);
}
}
Now, according to the comment, why will the second method fail even if the first method is called first? isn't the first method changing the value of s to lowercase?

#Before happens before each test. This means the order you run them in does not matter as it will always perform the setup then do the test.
The tag #BeforeClass will give you the behaviour you are expecting. This runs once before any of your tests start.

JUnit does not run each test case (method with #Test) in order of your code. That is why each test case must be independent of each other.
Also setup method with #Before tag will always get run before each of your test method.
So likelihood (but not necessarily) the order of execution of your code are:
setup()
testHelloWorldSuccess()
setup()
testHelloWorldFail()
But it might also run:
setup()
testHelloWorldFail()
setup()
testHelloWorldSuccess()

for JUnit , the order of testcase execution is not fixed. It may happen that you wrote a method m2 after method m1 and while execution, m2 gets executed first. The best approach is your test case should not be based on the testcase execution order.
try #BeforeClass if you want something to be executed once for the whole class only.
For the above scenario try this:
protected String s;
private int flag ;
#BeforeClass
public beforeClass(){
flag = 0;
}
#Before
public void setup() {
s = "HELLO WORLD";
}
#Test
public void testHelloWorldSuccess() {
flag = 1;
s = s.toLowerCase();
assertEquals("hello world", s);
}
// won't fail even if testHelloWorldSuccess is called first
#Test
public void testHelloWorldFail() {
if(flag == 1)
assertEquals("hello world", s);
else
assertEquals("HELLO WORLD", s);
}

Related

How to run same class multiple times using selenium

Is there any way that I can run a class 3 times or more in Selenium. So it runs in below order:
method1
method2
method3
method1
method2
method3
method1
method2
method3
import com.test
Class A{
#Test(priority =1)
public void method1(){`System.out.print('method1');`}
#Test(priority =2)
public void method2(){`System.out.print('method2');`}
#Test(priority =3)
public void method3(){`System.out.print('method3');`}
}
As far as I know, there is no easy way in TestNG to do so. Annotation parameter invocationCount only works on method level, not on class, so annotating your class with #Test(invocationCount = 3) doesn't work.
As you're mentioning Selenium, my guess is you are trying to automate some repeated actions on a webpage. If so, then I think ideologically your best bet is to extract code from these three methods and just write another test that calls those internals, like this:
#Test(priority = 1)
public void method1() {
stuff1();
}
#Test(priority = 2)
public void method2() {
stuff2();
}
#Test(priority = 3)
public void method3() {
stuff3();
}
#Test
public void complexTest() {
for (int i = 0; i < 3; i++) {
stuff1();
stuff2();
stuff3();
}
}
private void stuff1() {
System.out.print("method1");
}
private void stuff2() {
System.out.print("method2");
}
private void stuff3() {
System.out.print("method3");
}
It's a good practice to treat each test as atomic test that can either fail or pass, and if you want to test some scenario that does particular set of actions three times, better introduce new test for this and make it clearly and explicitly "tell a story" of test.

Unit test of a function calling 2 tested functions inside the same class

I have the following skeleton of code in a JAVA class called "TestClass.Java":
public String functionA () {
if (function B() == true) {
String testVariable = function C();
String test2 = testVariable +"Here a test";
} else {
...
}
}
I need to apply unit tests for this function functionA() where tests had been applied on functionB() and functionC():
I did below:
private TestClass mockTestClass ;
#Test
public void testFunctionA() {
mockTestClass = Mockito.mock(TestClass.class);
private MockComponentWorker mockito;
Mockito.when(mockTestClass.functionB()).thenReturn(true);//already test is done;
Mockito.when(mockTestClass.functionC()).thenReturn("test"); //already test is done;
mockito = mockitoContainer.getMockWorker();
mockito.addMock(TestClass.class,mockTestClass);
mockito.init();
assertEquals("PAssed!", "test Here a test", mockTestClass.functionA());
}
When I ran my test, I got: NULL in mockTestClass.functionA().
Can you please help? How to test this function?
You would generally want to mock other classes and not the class you are actually testing. But for your example if you really want to mock calling functionB() and functionC() you need to spy on TestClass. And instead of Mockito.when(mockTestClass.functionB()).thenReturn(true) you need doReturn(true).when(mockTestClass).functionB() (same goes for functionC()). Only then your assertEquals("PAssed!", "test Here a test", mockTestClass.functionA()) will call the actual method functionA() and pass.

How to do junit testing for multiple functions together

I am writing Junit test cases for one java application.
If I run the test functions individually its running fine.
When I try to run them together its not running properly
Here is JUnit code
public class CultureMachineTestCases{
CultureMachineAssignment testObj=new CultureMachineAssignment ();
HashSet<String> result =new HashSet<String>();
String answer,answer1;
int flagVal;
#Before
public void init() throws IOException{
testObj.insertDataIntoSet();
testObj.addKeywords("video1");
}
#Test
public void testVideo() throws IOException {
result=testObj.search("abcd");
answer=result.toString();
answer1=answer.replaceAll("[^a-z0-9]","");
assertEquals("video1", answer1);
}
#Before
public void initMethod() throws IOException{
testObj.insertDataIntoSet();
testObj.addKeywords("video2");
}
#Test
public void testLenth() throws IOException{
flagVal=testObj.flag;
assertEquals(1, flagVal);
}
}
Here flag is set to one in CultureMachineAssignment file.
Can any one please tell me what I need to do so I can run all the functions inside test file together
#Before annotated method (init()) is called before every test method. You should only have one method annotated with #Before not to get confused.
The code you have implemented in init() should be moved to testVideo() and code from initMethod() should be moved to testLength().
And your init method should look like this to be sure that test class state is the same for all tests:
#Before
public void init(){
answer = null;
answer1 = null;
flagVal = -1;
result = new HashSet<String>();
}

How can I make sure my JUnit test method's specific cleanup always runs?

I have a JUnit test class that has two test methods:
#Test
public void test1() {
// Setup: Create foo1.m
// Exercise
// Tear Down: Delete foo1.m
}
#Test
public void test2() {
// Setup: Create foo2.m
// Exercise
// Tear Down: Delete foo2.m
}
For each method, I would like to make sure that, if the Exercise section fails for any reason, the Tear Down will still run. Note that the Setup and Tear Down code for both test methods are different, so I don't think I can use JUnit's #Before and #After annotations to do what I want.
I could put TRY-CATCH blocks into each test method:
#Test
public void test2() {
// Setup: Create foo2.m
try {
// Exercise
} finally {
// Tear Down: Delete foo2.m
}
}
but that seems ugly. Is there a way to make sure the test-method-specific tear down code in each test method is executed, without using a TRY-CATCH block?
If the setup and teardown are different, you are essentially cramming two different test fixtures into a single file. The sensible answer is to put them in separate files and use the normal annotations. If they have anything in common separate that out into a common abstract class.
Adding multiple setups in the same file can easily result in a situation where it's not clear which instance members are used in which tests, so that maintaining the tests becomes a lot harder than it needs to be.
Update:
I found a better solution, so I include here, the original answer can be found below. I think JUnit 4 rules can be used here:
class PrepareFile implements org.junit.rules.TestRule {
#Retention(RetentionPolicy.RUNTIME)
public #interface FileName {
String value() default "";
}
#Override
public Statement apply(final Statement statement, final Description description) {
return new Statement() {
#Override
public void evaluate() throws Throwable {
String fileName = description.getAnnotation(FileName.class).value();
File file = new File(fileName);
try {
file.createNewFile();
statement.evaluate();
} finally {
file.delete();
}
}
};
}
}
Using it in the test:
#Rule
public PrepareFile prepareFile = new PrepareFile();
#Test
#PrepareFile.FileName("foo1.m")
public void test1() {
// Exercise
}
#Test
#PrepareFile.FileName("foo2.m")
public void test2() {
// Exercise
}
Here comes my original answer:
You may try to use the #BeforeClass and #AfterClass annotations.
#BeforeClass
public static void setUp() {
// Setup1: Create foo1.m
// Setup2: Create foo2.m
}
#AfterClass
public static void tearDown() {
// Tear Down1: Delete foo1.m
// Tear Down2: Delete foo2.m
}
#Test
public void test1() {
// Exercise
}
#Test
public void test2() {
// Exercise
}
This way you can setup and tear down all test cases once and the framework ensures that teadDown() is called in case of errors as well.

How to tell a Mockito mock object to return something different the next time it is called?

So, I'm creating a mock object as a static variable on the class level like so... In one test, I want Foo.someMethod() to return a certain value, while in another test, I want it to return a different value. The problem I'm having is that it seems I need to rebuild the mocks to get this to work correctly. I'd like to avoid rebuilding the mocks, and just use the same objects in each test.
class TestClass {
private static Foo mockFoo;
#BeforeClass
public static void setUp() {
mockFoo = mock(Foo.class);
}
#Test
public void test1() {
when(mockFoo.someMethod()).thenReturn(0);
TestObject testObj = new TestObject(mockFoo);
testObj.bar(); // calls mockFoo.someMethod(), receiving 0 as the value
}
#Test
public void test2() {
when(mockFoo.someMethod()).thenReturn(1);
TestObject testObj = new TestObject(mockFoo);
testObj.bar(); // calls mockFoo.someMethod(), STILL receiving 0 as the value, instead of expected 1.
}
}
In the second test, I'm still receiving 0 as the value when testObj.bar() is called... What is the best way to resolve this? Note that I know I could use a different mock of Foo in each test, however, I have to chain multiple requests off of mockFoo, meaning I'd have to do the chaining in each test.
You could also Stub Consecutive Calls (#10 in 2.8.9 api). In this case, you would use multiple thenReturn calls or one thenReturn call with multiple parameters (varargs).
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.junit.Before;
import org.junit.Test;
public class TestClass {
private Foo mockFoo;
#Before
public void setup() {
setupFoo();
}
#Test
public void testFoo() {
TestObject testObj = new TestObject(mockFoo);
assertEquals(0, testObj.bar());
assertEquals(1, testObj.bar());
assertEquals(-1, testObj.bar());
assertEquals(-1, testObj.bar());
}
private void setupFoo() {
mockFoo = mock(Foo.class);
when(mockFoo.someMethod())
.thenReturn(0)
.thenReturn(1)
.thenReturn(-1); //any subsequent call will return -1
// Or a bit shorter with varargs:
when(mockFoo.someMethod())
.thenReturn(0, 1, -1); //any subsequent call will return -1
}
}
For all who search to return something and then for another call throw exception:
when(mockFoo.someMethod())
.thenReturn(obj1)
.thenReturn(obj2)
.thenThrow(new RuntimeException("Fail"));
or
when(mockFoo.someMethod())
.thenReturn(obj1, obj2)
.thenThrow(new RuntimeException("Fail"));
First of all don't make the mock static. Make it a private field. Just put your setUp class in the #Before not #BeforeClass. It might be run a bunch, but it's cheap.
Secondly, the way you have it right now is the correct way to get a mock to return something different depending on the test.
Or, even cleaner:
when(mockFoo.someMethod()).thenReturn(obj1, obj2);
For Anyone using spy() and the doReturn() instead of the when() method:
what you need to return different object on different calls is this:
doReturn(obj1).doReturn(obj2).when(this.spyFoo).someMethod();
.
For classic mocks:
when(this.mockFoo.someMethod()).thenReturn(obj1, obj2);
or with an exception being thrown:
when(mockFoo.someMethod())
.thenReturn(obj1)
.thenThrow(new IllegalArgumentException())
.thenReturn(obj2, obj3);

Categories

Resources