value of global variable is changing to null in JUnit - java

I wrote a simple class, in which first function's output is second function's input and second function's output is third function's input.
After that I am printing these outputs in another class which implements JUnit #Test cases.
But for call to second function's test, I'm getting 'res' value as null(which should be output of first function and passing it as input to second function). Same is the case with third function.
I'm declaring 'res' as global variable. Then why is its value changing to null instead of holding the result of first function and then of second function( for call to third function) ?
Here is the class which contains 3 functions:
package con.nc.junitexmples.Junit4Examples;
public class StringExample {
public static String firstFunction() {
String msg1 = "msg1";
return msg1;
}
public static String secondFunction(String msg1) {
String msg2 = msg1+"msg2";
return msg2;
}
public static String thirdFunction(String msg2) {
String msg3= msg2+"msg3";
return msg3;
}
}
Here is class which implements JUnit #Test cases and printing output:
package con.nc.junitexmples.Junit4Examples;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;
#FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class TestStringExample {
String res;
#BeforeClass
public static void setUpBeforeClass() throws Exception {
System.out.println("\n\t\t-----JUnit cascading input Example------\n\n");
System.out.println("before class---->only once");
}
#Before
public void setUp() throws Exception {
System.out.println("\nbefore--->before each test case");
}
#Test
public void testFirstFunction(){
System.out.println("\ttest case: FIRST Function");
res = StringExample.firstFunction();
System.out.println("\t"+res);
}
#Test
public void testSecondFunction(){
System.out.println("\ttest case: SECOND Function");
res = StringExample.secondFunction(res);
System.out.println("\t"+res);
}
#Test
public void testThirdFunction(){
System.out.println("\ttest case: THIRD Function");
res = StringExample.thirdFunction(res);
System.out.println("\t"+res);
}
#After
public void tearDown() throws Exception {
System.out.println("after ---> after each test case\n\n");
}
#AfterClass
public static void tearDownAfterClass() throws Exception {
System.out.println("after class--->only once");
}
}
And here is the output I'm getting:
-----JUnit cascading input Example------
before class---->only once
before--->before each test case
test case: FIRST Function
msg1
after ---> after each test case
before--->before each test case
test case: SECOND Function
**nullmsg2**
after ---> after each test case
before--->before each test case
test case: THIRD Function
**nullmsg3**
after ---> after each test case
after class--->only once
How do I pass result of first function to second as input and so on?

Each of these tests is self contained, independent and the value of res at the start of these tests methods is null.
So, that explains why you are seeing:
nullmsg2
nullmsg3
Given this question from the comments above:
how do I pass output of first function as input to second function for second test?
You could test all three calls in one test method, like so:
#Test
public void testAll() {
String res = StringExample.firstFunction();
Assert.assertEquals("msg1", res);
res = StringExample.secondFunction(res);
Assert.assertEquals("msg1msg2", res);
res = StringExample.thirdFunction(res);
Assert.assertEquals("msg1msg2msg3", res);
}

For pass the result of first function to second function:
#Test
public void testSecondFunction(){
System.out.println("\ttest case: SECOND Function");
String resFromFirstFunc = StringExample.firstFunction();
res = StringExample.secondFunction(resFromFirstFunc);
System.out.println("\t"+res);
}
But you shouldn't write the test like above example, it always passed.
You should use:
Assert.assertEquals(input,output)

Related

Error when using the same string in different tests

I have the following scenario:
I perform several tests (#Test) and tests in Cucumber, in Selenium Webdriver, Java.
The tests are going well. However, I want to leave a string stored in one #Test (public void) in another #Test (public void). I cannot.
Could anyone help?
First test:
#Test
public void testDocuments() {
OneClass oneClass = new OneClass();
oneClass.one();
oneClass.two();
}
Second test:
#Test
public void testDocuments() {
OneClass oneClass = new OneClass();
oneClass.one();
oneClass.two();
}
Method one
public String one() {
if (this.cnpj == null) {
this.cnpj = add.cnpj(false);
} else {
}
return this.cnpj;
}
Both tests I want you to use the same generated string !!!!
I look forward and thanks in advance!
I'm not sure what your method one() does, but assuming you want to use the same value for two different tests, why not just do this:
OneClass oneClass = new OneClass();
String yourGeneratedString = oneClass.one();
// First test
#Test
public void testDocuments() {
yourFunction(yourGeneratedString);
}
// Second test
#Test
public void testDocuments2() {
yourOtherFunction(yourGeneratedString);
}
If I understand correctly, you need this.cnpj value to be available within the second test?
Each time you do new OneClass() , it creates a new instance of it.
So you can do one of the following:
Use singleton instance of OneClass
Make cnpj a static field within OneClass
If I understand it right, you want to share data from one test to second one. If you user testNG then you can do it this way.
import org.testng.ITestContext;
import org.testng.annotations.Test;
public class MyTest {
#Test
public void testOne(ITestContext context){
context.setAttribute("myKey", "myValue");
}
#Test
public void testTwo(ITestContext context){
String valueFromTestOne = (String) context.getAttribute("myKey");
System.out.println("My key = " + valueFromTestOne);
}
}

iterative testing using junit

I have a bunch of test inputs that I would like to run and compare the output with expected:
#Test
void test () throws IOExeption {
for (File i : readDir()) {
File out = foo(i);
assertEquals(FileUtils.readLines(expected), FileUtils.readLines(out));
}
}
I would like to run the tests using JUnit. But if I do it like the above then JUnit will stop after encountering the first test failure. Is there a better way to do this other than making each file its own test case like below?
#Test
void test1 () throws IOExeption {
File i = readFile("1.txt");
File out = foo(i);
assertEquals(FileUtils.readLines(expected), FileUtils.readLines(out));
}
#Test
void test2 () throws IOExeption {
File i = readFile("2.txt");
File out = foo(i);
assertEquals(FileUtils.readLines(expected), FileUtils.readLines(out));
}
I think, that you could use Parameterized. This is standard feature of JUnit. Below you can see an example.
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.util.Arrays;
import java.util.Collection;
#RunWith(Parameterized.class)
public class Foo {
#Parameterized.Parameters
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][] { { "1.txt" }, { "2.txt" } });
}
#Parameterized.Parameter // first data value (0) is default
public /* NOT private */ String fileName;
#Test
public void test() {
File i = readFile(fileName);
File out = foo(i);
assertEquals(FileUtils.readLines(expected), FileUtils.readLines(out));
}
}
I have not found JUnit official documentation about this, but you can find more details e.g. in this tutorial: https://www.tutorialspoint.com/junit/junit_parameterized_test.htm

Mocking chained methods calls using PowerMock

I have a class which I would like to test with a public static method that contains some chained method calls. Assuming that an exception occurs during the chained method calls, how do I handle this effectively and make it return some specific value?
Following is the code sample of the test class.
#RunWith(PowerMockRunner.class)
#PrepareForTest({CodeWithPrivateMethod.class,CodeWithAnotherPrivateMethod.class,CodeWithYetAnotherPrivateMethod.class})
public class CodeWithPrivateMethodTest {
#Test
public void when_gambling_is_true_then_always_explode() throws Exception {
CodeWithYetAnotherPrivateMethod codeWithYetAnotherPrivateMethod = PowerMockito.spy(new CodeWithYetAnotherPrivateMethod());
PowerMockito.whenNew(CodeWithYetAnotherPrivateMethod.class).withAnyArguments().thenReturn(codeWithYetAnotherPrivateMethod);
CodeWithAnotherPrivateMethod codeWithAnotherPrivateMethod = PowerMockito.spy(new CodeWithAnotherPrivateMethod());
PowerMockito.whenNew(CodeWithAnotherPrivateMethod.class).withAnyArguments().thenReturn(codeWithAnotherPrivateMethod);
PowerMockito.doReturn(true).when(codeWithYetAnotherPrivateMethod, "getGambling");
//PowerMockito.doReturn(codeWithYetAnotherPrivateMethod).when(codeWithAnotherPrivateMethod, "getGambleValue");
PowerMockito.spy(CodeWithPrivateMethod.class);
CodeWithPrivateMethod.startGamble();
}
}
Following is the code sample for the class under test
public class CodeWithPrivateMethod {
public static void startGamble() {
Boolean gamble = CodeWithAnotherPrivateMethod.getGambleValue()
.getGambling();
if (gamble) {
System.out.println("kaboom");
}else{
System.out.println("boom boom");
}
}
}
Following is the code sample for the class that gets called from the class under test
public class CodeWithAnotherPrivateMethod {
static CodeWithYetAnotherPrivateMethod codeWithYetAnotherPrivateMethod = new CodeWithYetAnotherPrivateMethod();
public static CodeWithYetAnotherPrivateMethod getGambleValue() {
return codeWithYetAnotherPrivateMethod; //works fine
return null; // fails
}
}
Following is the code sample for the other class that gets called from the class under test
public class CodeWithYetAnotherPrivateMethod {
public Boolean getGambling() {
return false;
}
}
So Assuming I return a null value from getGambleValue() method of CodeWithAnotherPrivateMethod class, how do I handle this null value effectively in my testclass?
This is how to specify expected exceptions using Mockito:
#Test(expected = NullPointerException.class)
public void when_gambling_is_true_then_always_explode() throws Exception {
...
Before I found out about this I would do:
#Test
public void when_gambling_is_true_then_always_explode() throws Exception {
// setup omitted
try {
CodeWithPrivateMethod.startGamble();
}
catch(NullPointerException e) {
// expected
return;
}
fail("Expected NullPointerException");
}
EDIT: Testing multiple classes that call each other statically like this is a severe code smell. Unit tests should test a single class and inline static calls should be limited to utility classes.
Another comment: your example class names are very confusing. Next time please stick with Foo, Bar, Baz or Appple, Pear, Banana.
If you are not getting an NPE then I expect your mocking/spying is interfering. If you call the code under test without mocking/spying the call chain would be:
CodeWithPrivateMethod.startGamble();
->
CodeWithYetAnotherPrivateMethod value = CodeWithAnotherPrivateMethod.getGambleValue();
->
return null;
<-
value.getGambling();
<- throws NullPointerException
What exactly are you trying to find out or achieve?
EDIT: Here's how it should work with PowerMock
#RunWith(PowerMockRunner.class)
#PrepareForTest(CodeWithAnotherPrivateMethod.class)
public class CodeWithPrivateMethodTest {
#Mock
private CodeWithYetAnotherPrivateMethod yetAnotherInstance;
#Test
public final void testStartGamble() {
// SETUP
mockStatic(CodeWithAnotherPrivateMethod.class);
expect(CodeWithAnotherPrivateMethod.getGambleValue())
.andReturn(yetAnotherInstance);
Boolean gamblingValue = true;
expect(yetAnotherInstance.getGambling()).andReturn(gamblingValue);
replayAll();
// CALL
CodeWithPrivateMethod.startGamble();
// VERIFY
verifyAll();
}

Passing parameter to #Before setup in jUnit test [duplicate]

This question already has answers here:
Is it possible to use different #Before #After for each test case in JUnit?
(2 answers)
Closed 8 years ago.
Is there any way to avoid calling populateRandomData() method at the begining of each test without having a fixed parameter 100. I need to call the same method to setup data before execution of each test but I need to change the number of test data entries e.g. 100 in each case .
public class Tester
{
#Before
public void setUp() {
populateRandomData(100)
}
#Test
public void testMethod() {
}
private void populateRandomData(n){
//n times insert random data in table.
}
}
You can create Parameterized JUnit Test which allows you to add number of parameters you want to pass in unit test case. Have a look at example tutorial Create Parameterized Test Case.
OR
#Rule, using this annotations on your test methods to parameterize the execution of your rules makes it even more useful. Taken from JUnit 4.7 #Rules
EDIT :
Example of Using #Rule :
Below is the class which allows you to initialize different value of num variable which will be used in test method :
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
public class Test1 implements TestRule {
private final int num;
public Test1(int num) {
this.num = num;
}
public int getNum() {
return num;
}
public class Test1Statement extends Statement {
private final Statement statement;
public Test1Statement(Statement statement, int num) {
this.statement = statement;
}
#Override
public void evaluate() throws Throwable {
statement.evaluate();
}
}
#Override
public Statement apply(Statement statement, Description description) {
return new Test1Statement(statement, num);
}
}
The class below is the actual test case class. It contains JUnit test cases & set value of num variable in test method.
import org.junit.Rule;
import org.junit.Test;
public class RuleNumberTester {
#Rule
public Test1 test = null;
#Rule
public Test1 test1 = null;
#Test
public void num1Test() {
test = new Test1(111);
System.out.println("Num 1 : " + test.getNum());
}
#Test
public void num2Test() {
test1 = new Test1(222);
System.out.println("Num 2 : " + test1.getNum());
}
}
Output :
Test cases are executed successfully & shows the values of num variable which was initialized in test methods on console.
Num 1 : 111
Num 2 : 222
I suppose you could use a #Rule to ensure populateRandomData() is called each time with the correct parameters.
However, this gets ugly quickly since you then need to maintain a list of test method names.
private static final Map<String, Integer> dataCounts = new HashMap<>();
static {
// list (or otherwise obtain) counts here
dataCounts.put("testMethod", 100);
}
#Rule
public TestWatcher watcher = new TestWatcher() {
#Override
protected void starting(Description description) {
Integer count = dataCounts.get(description.getMethodName());
assertNotNull(count);
populateRandomData(count.intValue());
};
};

Java passing value

I have three programs,
first does a selenium test
import com.thoughtworks.selenium.*;
import java.util.regex.Pattern;
import junit.framework.*;
public class MyTest extends SeleneseTestCase {
int flag_eco;
public void setUp() throws Exception {
setUp("http://www.mysite.com/", "*iexplore");
}
public void testMyTest() throws Exception {
selenium.open("/pages/static/homepage_logout.html");
selenium.type("username", "myuser");
selenium.type("password", "password");
selenium.click("//input[#value='LOGIN']");
selenium.waitForPageToLoad("30000");
selenium.click("Confirm");
selenium.waitForPageToLoad("30000");
selenium.click("link=Applications");
selenium.waitForPageToLoad("30000");
selenium.click("link=Journey");
selenium.waitForPageToLoad("30000");
selenium.click("link=Launch Application (MUST BE LOGGED IN)");
selenium.waitForPageToLoad("30000");
if((selenium.isTextPresent("Please enter one of the following:")))
{
System.out.println("Journey Working Fine");
flag_test= 0;
}
else
{
System.out.println("Journey Failed");
flag_test = 1;
}
selenium.selectFrame("topmenu");
selenium.click("link=Home");
}
public static Test suite() {
//method added
return new TestSuite(MyTest.class);
}
public void tearDown(){
//Added . Will be called when the test will complete
selenium.stop();
}
}
then a sendmail gettin the values from the selenium test
import java.util.*;
public class SendMail
{
public void send()
{
MyTest Test = new MyTest();
if (Test.flag_test==1)
{
System.out.println("Journey Failed");
}
else if(Test.flag_test==0)
{
System.out.println("Journey Working Fine");
}
}
}
main class calling both
import java.io.*;
import javax.servlet.*;
public class Test
{
public static void main(String args[])
{
MyTest tes = new MyTest();
junit.textui.TestRunner.run(tes.suite());
SendMail se = new SendMail();
se.send();
}
}
how do i pass the flag value from MyTest to SendMail
The flag should be public static (I don't see it defined in the code you provided) - i.e.
public class MyTest {
public static int flag;
// the rest of the code
}
in send() you can refer to it with MyTest.flag_test
Note, that this is not a good way of passing data, but in your case there isn't anything better.
I think you are doing something that shouldn't be done at all. Here's what I propose:
move the code that is changing the flag outside the test
include it in the test, in the appropriate place (as if it is there)
include it in SendMail as well.
Thus you won't need to invoke the test in order to obtain a flag.
Three ways of achieving this
1. Pass the test as parameter to SendMail (already mentioned)
2. Write a listener on test, (Observable pattern/ PropertyChangeSupport in java) and hook it up. (Best IMO)
3. Write to a Static object which acts as white board and read from there. ( a poor man's message queue)

Categories