TestTraits.java

public interface TestTraits {
    String EMPLOYEE_ID = "1";
    Long EMPLOYEE_ID_LONG = 1L;

    default EmployeeRpy getEmployee(){
        EmployeeRpy objEmpRpy = new EmployeeRpy();
        objEmpRpy.setEmpName("Mugil");
        objEmpRpy.setEmpAge("34");
        return objEmpRpy;

     default EmployeeDetailsResource createMockedEmployeeDetails() 
          throws IOException(){
       EmployeeDetailsResource objEmployeeDetailsResource = 
              new Gson.fromJson(getReader("json-data/EmployeeDetails.json"), EmployeeDetails.class);    
       return objEmployeeDetailsResource; 
     } 

     default Reader getReader(String filePath) throws IOException{
       return new FileReader(new ClassPathResource(filePath).getFile());  
     }
}

EmployeeDetails.json

  {
     "empID" : "101",
     "empName" : "Mugilvannan",
     "empAge" : "30"
  } 

EmployeeMgmtTest.java

 @ExtendWith({MockitoExtension.class})
 class EmployeeMgmtTest implements TestTraits{
    .
    . 
    Code for Testing Goes Here
    .
    .
 }

What @Springbootapplication does?

@SpringBootApplication = @Configuration + @ComponentScan + @EnableAutoConfiguration

  1. @Configuration to enable Java-based configuration
  2. @ComponentScan – This annotation enables component-scanning so that the web controller classes and other components you create will be automatically discovered and registered as beans in Spring’s Application Context. All the@Controller classes you write are discovered by this annotation..
  3. @EnableAutoConfiguration annotation tells Spring Boot to “guess” how you will want to configure Spring, based on the jar dependencies that you have added. For example, If HSQLDB is on your classpath, and you have not manually configured any database connection beans, then Spring will auto-configure an in-memory database.For example, if you add spring-boot-starter-web dependency in your classpath, it automatically configures Tomcat and Spring MVC.
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    

What @springboottest annotation should do?

  1. Should check whether Java-based configuration are loaded
  2. Should do component scan and create beans.
  3. Should assign appropriate beans by resolving

@SpringBootTest annotation is used to bootstrap the entire container. The annotation works by creating the ApplicationContext that will be utilized in our tests. @SpringBootTest annotation works by creating the ApplicationContext used in our tests through SpringApplication.It starts the embedded server, creates a web environment and then enables @Test methods to do integration testing.

  1. Below we have two class DBConfig.java and DBProperties.java.
  2. DBConfig loads DBProperties bean. DBProperties bean gets its value from application.yml
  3. In the below integration test we are going to check whether all the classes are properly getting loaded into application context.
  4. Classes loaded using @SpringBootTest would be available only in the context of the class in which it is used. Just because you add the list of classes in TestConfigApplicationTests.java it wont be available in other test classes(DatasourceConfigTest.java, ExampleConfigurationTest.java)

DBProperties.java

package com.mugil.org.configs;

import org.springframework.boot.context.properties.ConfigurationProperties;

import java.util.ArrayList;
import java.util.List;

@ConfigurationProperties(prefix = "spring.datasource")
public class DBProperties {   
    private String userName;
    private String password;

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

DBConfig.java

@Configuration
@EnableConfigurationProperties(DBProperties.class) // Tells from which class is needed for creation of Beans
public class DBConfig {

    @Bean
    public DBProperties dbProperties(){
        DBProperties objDBProperties = new DBProperties();
        return objDBProperties;
    }
}

application.yml

spring:
  profiles:
    active: dev
---
spring:
  config:
    activate:
      on-profile: dev
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    password: root
    url: jdbc:mysql://localhost:3306/db
    username: root
  servers:
    - www.abc.test.com
    - www.xyz.test.com

---
spring:
  config:
    activate:
      on-profile: production
  datasource:
    driver-class-name: org.h2.Driver
    password: sa
    url: jdbc:h2:mem:db;DB_CLOSE_DELAY=-1
    username: sa
  servers:
    - www.abc.com
    - www.xyz.com

TestConfigApplication.java

package com.mugil.org;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class TestConfigApplication {
	public static void main(String[] args) {
		SpringApplication.run(TestConfigApplication.class, args);
	}
}

@SpringBootTest loads the DBConfig.java and creates DBProperties bean by reading values from application.yml file. The SpringBootTest ensures that all loading of beans defined in configuration file and all the values needed from application.yml and application.properties are available without any issue.

In case if you want to have any class to be autowired in @SpringBootTest class, the same should be defined in @SpringBootTest(classes = DBConfig.class) annotation.

The below @SpringBootTest takes classes which should be available by the time the application is bootstrapped. So we are expecting the properties to be read from application.yml and the bean gets created. Incase there is a problem the test case would fail below.

TestConfigApplication.java

package com.mugil.org;

import com.mugil.org.configs.DBConfig;
import com.mugil.org.configs.DBProperties;
import com.mugil.org.configs.ExampleConfiguration;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest(classes = {DBConfig.class})
class TestConfigApplicationTests {
	@Autowired
	DBProperties dbProperties;

	@Test
	void contextLoads() {
		System.out.println(dbProperties.getUserName());
	}
}

Below is a test which check if the value are loaded from yaml and is not null.
DatasourceConfigTest.java

package com.mugil.org.configs;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import static org.junit.jupiter.api.Assertions.assertNotNull;

@SpringBootTest(classes = DBConfig.class)
class DatasourceConfigTest{

    //This is same as using context.run method where the beans would be initialized
    //context.run method in our case is invoked because of @SpringBootTest defined class
    @Autowired
    DBProperties dbProperties;

    @Test
    public void dbConfigTest() throws Exception {
        final String name = dbProperties.getUserName();

        //We can check whether the property is getting loaded and its not null only not null
        assertNotNull(name);
    }
}
  1. The @SpringBootTest annotation tells Spring Boot to look for a main configuration class (one with @SpringBootApplication , for instance) and use that to start a Spring application context.
  2. Spring Boot Integration Testing is running an application in ApplicationContext and run tests.spring-boot-starter-test which will internally use spring-test and other dependent libraries
  3. @SpringBootTest annotation works by creating the ApplicationContext used in our tests through SpringApplication.It starts the embedded server, creates a web environment and then enables @Test methods to do integration testing.

ExampleConfiguration.java

package com.mugil.org.configs;

import com.mugil.org.services.ExampleService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ExampleConfiguration {

    @Bean
    ExampleService exampleService() {
        ExampleService exampleService = new ExampleService();
        return exampleService;
    }
}

Below is the testing of the same functionality in a different way. Instead of using @SpringBootTest we are loading the class with help of ApplicationContextRunner and checking whether the loaded class – ExampleConfiguration.java dependencies – ExampleService.java in turn gets loaded

How to check if bean from particular configuration is loaded
ExampleConfigurationTest.java

package com.mugil.org.configs;

import com.mugil.org.services.ExampleService;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;

import static org.assertj.core.api.Assertions.assertThat;

class ExampleConfigurationTest {

    /*
     * I setup a context runner with the class ExampleConfiguration
     * in it. For that, I use ApplicationContextRunner#withUserConfiguration()
     * methods to populate the context.
     */
    ApplicationContextRunner context = new ApplicationContextRunner()
            .withUserConfiguration(ExampleConfiguration.class);

    @Test
    public void should_check_presence_of_example_service() {
        /*
         * We start the context, and we will be able to trigger
         * assertions in a lambda receiving a
         * AssertableApplicationContext
         */

        context.run(it -> {
            /*
             * I can use assertThat to assert on the context
             * and check if the @Bean configured is present
             * (and unique)
             */
            assertThat(it).hasSingleBean(ExampleService.class);
        });
    }
}

new ApplicationContextRunner() creates a new context and creates the bean by loading the configuration

For further reference check the code in the Link

Below is a static util class which can be used to check the list of beans available in the application context

ExampleConfigurationTest.java

package com.mugil.org.utils;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;

@Service
public class SpringUtils implements ApplicationContextAware {
    private static ApplicationContext ctx;

    @Override
    public void setApplicationContext(ApplicationContext appContext)
            throws BeansException {
        ctx = appContext;
    }

    public static ApplicationContext getApplicationContext() {
        return ctx;
    }
}

} Below is a static util class that can be used to check the list of beans available in the application context

ExampleConfigurationTest.java

package com.mugil.org.utils;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;

@Service
public class SpringUtils implements ApplicationContextAware {
    private static ApplicationContext ctx;

    @Override
    public void setApplicationContext(ApplicationContext appContext)
            throws BeansException {
        ctx = appContext;
    }

    public static ApplicationContext getApplicationContext() {
        return ctx;
    }
}

SomeRandomClass.java

class SomeRandomClass
{
    @Autowired
    SpringUtils springUtils;

    
    public void getBeans() 
    {  
        String[] beans = springUtils.getApplicationContext().getBeanDefinitionNames();
        Arrays.sort(beans);
        for (String bean : beans)
        {
            System.out.println(bean + " of Type :: " + springUtils.getApplicationContext().getBean(bean).getClass());
        }
}
}

Output

DBConfig of Type :: class com.mugil.org.configs.DBConfig$$EnhancerBySpringCGLIB$$d32ee4ac
dbProperties of Type :: class com.mugil.org.configs.DBProperties
spring.datasource-com.mugil.org.configs.DBProperties of Type :: class com.mugil.org.configs.DBProperties
springUtils of Type :: class com.mugil.org.utils.SpringUtils

In case if you don’t want to create a separate class and wanted to access beans in the context you can implement the ApplicationContextAware interface and specify the for loop in overridden setApplicationContext method.

How to load a single class into ApplicationContext

.
.
ApplicationContextRunner context = new ApplicationContextRunner().withUserConfiguration(ExampleConfiguration.class);
.
.

TestTraits.java

package com.mugil.org;

import com.google.gson.Gson;
import com.mugil.org.models.Employee;
import org.springframework.core.io.ClassPathResource;

import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;

public interface TestTraits {
    public static Object getObjfromJson(String fileLoctaion) throws IOException {
        Gson gson = new Gson();
        Employee objEmployee2 = gson.fromJson(getReader(fileLoctaion), Employee.class);
        return objEmployee2;
    }

    public static Reader getReader(String fileLoctaion) throws IOException {
        return new FileReader(new ClassPathResource(fileLoctaion).getFile());
    }
}

EmployeeObject.json

{
  "empID": 101,
  "empName": "Mani",
  "empAge": "35"
}

EmployeeControllerTest.java
Read JSON Value as from File and Convert to Employee Object and to JSON String

JSON Value from File -> Employee Object -> JSON String from Object

  @Test
    void addEmployeeDetails() throws Exception {
        
        //Read values from JSON  
        Employee objEmployee = (Employee) TestTraits.getObjfromJson("json-data/EmployeeObject.json");

        //Convert Object to JSON String
        String jsonRequestString = mapper.writeValueAsString(objEmployee);

        when(employeeServiceImpl.saveEmployee(any())).thenReturn("101");

        ResultActions objResultActions = this.mockMvc.perform(post("/empmgmt/employees")
                .contentType(MediaType.APPLICATION_JSON)
                .content(jsonRequestString))
                .andDo(print())
                .andExpect(jsonPath("$.empID", is(Matchers.notNullValue())))
                .andExpect(jsonPath("$.empID", is(101)))
                .andExpect(jsonPath("$.empName", is("Mani")))
                .andExpect(status().isCreated());
    }

EmployeeControllerTest.java
Read JSON Value as from File and Convert to Employee Object and to JSON String

JSON Value from File -> Employee Object for Mocking Service Call


@Test
    void getEmployeeDetails() throws Exception {
          
        //Object Construction by reading file
        Employee objEmployee = (Employee) TestTraits.getObjfromJson("json-data/EmployeeObject.json");

        //Making object as Optional
        Optional<Employee> objEmp = Optional.ofNullable(objEmployee);

        //Mocked service response from object created
        when(employeeServiceImpl.findEmployee(EMP_ID)).thenReturn(objEmp);

        ResultActions objResultActions = this.mockMvc.perform(get("/empmgmt/employees/{empID}",EMP_ID))
                                                    .andDo(print())
                                                    .andExpect(jsonPath("$.empID", is(101)))
                                                    .andExpect(jsonPath("$.empName", is("Mani")))
                                                    .andExpect(jsonPath("$._links.all-employees.href", is("http://localhost/empmgmt/employees")))
                                                    .andExpect(status().isOk());
    }

Repo Link
https://bitbucket.org/Mugil/restwithspringboot/branch/feature/7MockMVCTesting_3

POST

 @Test
    void addEmployeeDetails() throws Exception {
        Employee objEmployee = (Employee) TestTraits.getObjfromJson("json-data/EmployeeObject.json");

        String jsonRequestString = mapper.writeValueAsString(objEmployee);

        when(employeeServiceImpl.saveEmployee(any())).thenReturn("101");

        ResultActions objResultActions = this.mockMvc.perform(post("/empmgmt/employees")
                .contentType(MediaType.APPLICATION_JSON)
                .content(jsonRequestString))
                .andDo(print())
                .andExpect(jsonPath("$.empID", is(Matchers.notNullValue())))
                .andExpect(jsonPath("$.empID", is(101)))
                .andExpect(jsonPath("$.empName", is("Mani")))
                .andExpect(status().isCreated());
    }

GET

 @Test
    void getEmployeeDetails() throws Exception {
        ClassLoader loader = Test.class.getClassLoader();
        Employee objEmployee = (Employee) TestTraits.getObjfromJson("json-data/EmployeeObject.json");

        Optional<Employee> objEmp = Optional.ofNullable(objEmployee);
        when(employeeServiceImpl.findEmployee(EMP_ID)).thenReturn(objEmp);

        ResultActions objResultActions = this.mockMvc.perform(get("/empmgmt/employees/{empID}",EMP_ID))
                                                    .andDo(print())
                                                    .andExpect(jsonPath("$.empID", is(101)))
                                                    .andExpect(jsonPath("$.empName", is("Mani")))
                                                    .andExpect(jsonPath("$._links.all-employees.href", is("http://localhost/empmgmt/employees")))
                                                    .andExpect(status().isOk());
    }

DELETE

 @Test
    void deleteEmployeeDetails() throws Exception {
        when(employeeServiceImpl.deleteEmployee(Long.valueOf(EMP_ID))).thenReturn(true);

        this.mockMvc.perform(delete("/empmgmt/employees/{empID}",EMP_ID))
                .andDo(print())
                .andExpect(content().string(containsString("Employee Deleted Successfully")))
                .andExpect(status().isOk());
    }

EmployeeControllerTest.java

package com.mugil.org.controllers;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.mugil.org.TestTraits;
import com.mugil.org.models.Employee;
import com.mugil.org.services.EmployeeServiceImpl;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.is;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

@ExtendWith(SpringExtension.class)
@WebMvcTest(EmployeeController.class)
class EmployeeControllerTest {

    @MockBean
    EmployeeServiceImpl employeeServiceImpl;

    ObjectMapper mapper = new ObjectMapper();

    @Autowired
    private MockMvc mockMvc;

    private static final String EMP_ID = "101";

    @Test
    void getEmployeeDetails() throws Exception {
        ClassLoader loader = Test.class.getClassLoader();
        Employee objEmployee = (Employee) TestTraits.getObjfromJson("json-data/EmployeeObject.json");

        Optional<Employee> objEmp = Optional.ofNullable(objEmployee);
        when(employeeServiceImpl.findEmployee(EMP_ID)).thenReturn(objEmp);

        ResultActions objResultActions = this.mockMvc.perform(get("/empmgmt/employees/{empID}",EMP_ID))
                                                    .andDo(print())
                                                    .andExpect(jsonPath("$.empID", is(101)))
                                                    .andExpect(jsonPath("$.empName", is("Mani")))
                                                    .andExpect(jsonPath("$._links.all-employees.href", is("http://localhost/empmgmt/employees")))
                                                    .andExpect(status().isOk());
    }

    @Test
    void deleteEmployeeDetails() throws Exception {
        when(employeeServiceImpl.deleteEmployee(Long.valueOf(EMP_ID))).thenReturn(true);

        this.mockMvc.perform(delete("/empmgmt/employees/{empID}",EMP_ID))
                .andDo(print())
                .andExpect(content().string(containsString("Employee Deleted Successfully")))
                .andExpect(status().isOk());
    }

    @Test
    void getAllEmployeeDetails() throws Exception {
        List<Employee> arrEmployees = new ArrayList<>();
        arrEmployees.add(getEmployee());

        when(employeeServiceImpl.findAllEmployee()).thenReturn(arrEmployees);

        ResultActions objResultActions = this.mockMvc.perform(get("/empmgmt/employees")
                .contentType(MediaType.APPLICATION_JSON))
                .andDo(print())
                .andExpect(jsonPath("$[0].empID", is(Matchers.notNullValue())))
                .andExpect(jsonPath("$[0].empID", is(101)))
                .andExpect(jsonPath("$[0].empName", is("Shivaji")))
                .andExpect(status().is2xxSuccessful());
    }

    @Test
    void addEmployeeDetails() throws Exception {
        Employee objEmployee = (Employee) TestTraits.getObjfromJson("json-data/EmployeeObject.json");

        String jsonRequestString = mapper.writeValueAsString(objEmployee);

        when(employeeServiceImpl.saveEmployee(any())).thenReturn("101");

        ResultActions objResultActions = this.mockMvc.perform(post("/empmgmt/employees")
                .contentType(MediaType.APPLICATION_JSON)
                .content(jsonRequestString))
                .andDo(print())
                .andExpect(jsonPath("$.empID", is(Matchers.notNullValue())))
                .andExpect(jsonPath("$.empID", is(101)))
                .andExpect(jsonPath("$.empName", is("Mani")))
                .andExpect(status().isCreated());
    }

    private Employee getEmployee(){
        Employee objEmployee = new Employee();

        objEmployee.setEmpID(Long.valueOf(101));
        objEmployee.setEmpAge("35");
        objEmployee.setEmpName("Shivaji");

        return objEmployee;
    }
}

Testing Output using assertEquals
Scenario1.java

public class Scenario
{	
  public int Square(int no)
  {
    return no*no;
  }
}

SquareTest.java

public class SquareTest 
{
  @Test
  public void test() 
  {
    int SquareNo = new Test1().Square(5);		
    assertEquals(25, SquareNo);
  }
}

Scenario2.java(word Counter)

public class Scenario2 
{	
 public int repeatedWords(String pWord)
 {
   int count = 0;
	
   for (int j = 0; j < pWord.length(); j++) 
   {
     if(pWord.charAt(j) == 'a')
     {
       count++;	
     }
   }	
    return count;
 }
}

RepeatTest.java

public class RepeatTest {
   @Test
   public void test() {
     Scenario2 objScenario2 = new Scenario2();		
     assertEquals(objScenario2.repeatedWords("alphabet"), 2);		
   }
}

Test suite is used to bundle a few unit test cases and run them together. In JUnit, both @RunWith and @SuiteClasses annotations are used to run the suite tests.

AllTests.java (TestSuite)

@RunWith(Suite.class)
@SuiteClasses({ RepeatTest.class, SquareTest.class })
public class AllTests {

}

Now Lets take a Real Life Scenario of Bank Account
Account.java

public class Account 
{
	public int Balance;
	
	public Account()
	{
		Balance = 0;
	}
	
	public int getAccBalance()
	{
		return Balance;
	}
	
	public void getCash(int pCash)
	{
		Balance = Balance - pCash;
	}
	
	public void putCash(int pCash)
	{
		Balance = Balance + pCash;
	}
}

BankTest.java

public class BankTest 
{
	Account objAcc = new Account();
	
	@Test
	public void checkAccBalanceTest()
	{
		assertEquals(objAcc.getAccBalance(), 0);
	}
	
	@Test
	public void checkBalAfterDepositTest()
	{
		objAcc.putCash(50);
		assertEquals(objAcc.getAccBalance(), 50);
	}
	
	@Test
	public void checkBalAfterWithdrawTest()
	{
		objAcc.getCash(30);		
		assertEquals(objAcc.getAccBalance(), 20);
	}
}

Points to Note

  1. The methods in BankTest ends with Test Suffix.This ensures the test cases are executed in order.
  2. The Account.java and BankTest.java are two different projects.In BankTest project the other project is added in Java Build Path

DBUtilsTest.java

public class DBUtilsTest
{	
	public void getDBRecordsSQLTest()
	{	
		DBUtils objDBUtils 	 = new DBUtils();
		ResultSet resultSet  = objDBUtils.getDBRecordsSQL("SELECT 78985450.1245487986418648 decimal_val FROM dual");
		
		double expectedValue   = 1245.654618764;
		double dbValue 	 	   = 0; 
		double toleranceLimit  = 0.000000001;
		
		try
		{
			 while(resultSet.next())
			 {
				dbValue =  resultSet.getDouble("decimal_val");
				assertEquals(expectedValue, dbValue, toleranceLimit);
			 }
		} catch (SQLException e)
		{
			e.printStackTrace();
		}
		
		objDBUtils.closeConnection();
	}
	
	@Test
	public void getDBRecordsProcTest()
	{	
		DBUtils objDBUtils 	 = new DBUtils();
		ResultSet resultSet  = objDBUtils.getDBRecordsProc("{call TESTJUNIT.junitproc(?)}");
		
		double expectedValue   = 7.89854501245488E7;
		double dbValue 	 	   = 0; 
		double toleranceLimit  = 0.000000001;
		
		try
		{
			 while(resultSet.next())
			 {
				dbValue =  (double) resultSet.getDouble(1);				
				assertEquals(expectedValue, dbValue, toleranceLimit);
			 }
		} catch (SQLException e)
		{
			e.printStackTrace();
		}
		
		objDBUtils.closeConnection();
	}
}

DBUtils.java

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import oracle.jdbc.OracleTypes;

public class DBUtils
{
	Connection  conn  = null;
    Statement 	stmt  = null;
    ResultSet   rs    = null;
	
	public ResultSet getDBRecordsSQL(String pQuery)
	{    
	    try
	    {
	    	conn = DriverManager.getConnection("hostname", "admin", "admin123");
	        stmt = (Statement)conn.createStatement();
	        rs 	 = stmt.executeQuery(pQuery);
	     	
	    } catch (SQLException e)
		{
			e.printStackTrace();
		}
	    
		return rs;
	}
	
	public ResultSet getDBRecordsProc(String pQuery)
	{	
		CallableStatement stmt  = null; 
		
		try
	    {
	    	conn = DriverManager.getConnection("hostname", "admin", "admin123");	        
	        stmt = conn.prepareCall(pQuery);	        
	        stmt.registerOutParameter(1, OracleTypes.CURSOR);
	        stmt.execute();
	        rs = (ResultSet) stmt.getObject(1);
	    } catch (SQLException e)
		{
			e.printStackTrace();
		}
		
		return rs;
	}
	
	public void closeConnection()
	{
		if (rs  != null) try { rs.close();  } catch (SQLException ignore) {}
        if (stmt  != null) try { stmt.close();  } catch (SQLException ignore) {}
        if (conn != null) try { conn.close(); } catch (SQLException ignore) {}
	}
}

Element Locators using XPath

Expressions

 xpath=xpathExpression
   xpath=//img[@alt='The image alt text']
   xpath=//table[@id='table1']//tr[4]/td[2]
   xpath=//a[contains(@href,'#id1')]
   xpath=//a[contains(@href,'#id1')]/@class
   xpath=(//table[@class='stylee'])//th[text()='theHeaderText']/../td
   xpath=//input[@name='name2' and @value='yes']
   xpath=//*[text()="right"]

DOM – Javascript

 xpath=xpathExpression
 dom=document.forms['myForm'].myDropdown
 dom=document.images[56]
 dom=function foo() { return document.links[1]; }; foo();

How to find particular text in web driver method

WebDriver driver = new FirefoxDriver();
driver.get("https://localhost:8080/Login");

//Finds the xpath of element which contains UserName
WebElement strElemnt1 = driver.findElement(By.xpath("html/body/div[1]/div[2]/div[2]/div[2]/p[1]/b"));

How to get Last Row in Table

//How to get Last Row in Table 
String cssLast="table[class='dataTable']>tr:first-child>td:last-child"
String cssFirst="table[class='dataTable']>tr:last-child>td:last-child"

driver.findElement(By.cssSelector(cssLast)).getText();
driver.findElement(By.cssSelector(cssFirst)).getText();

By Using XPath

//By Using XPath
WebElement lastCellInFirstRow = driver.findElement(By.xpath("table[@class='dataTable']//tr[1]//td[last()]"));
WebElement lastCellInLastRow = driver.findElement(By.xpath("table[@class='dataTable']//tr[last()]//td[last()]"));

How to detect custom attribute

//How to detect custom attribute 
assertTrue(selenium.isElementPresent("//*[@btn-tag-title='Sign In']"));
selenium.click("//*[@btn-tag-title='Sign In']");

assertTrue(selenium.isElementPresent("css=*[btn-tag-title='Sign In']"));
selenium.click("css=*[btn-tag-title='Sign In']");

Finding custom attribute of span where attr=”data-automation-id” and val=”SEL_ERR”

//HTML Code
<span data-automation-id="SEL_ERR">
  Error Description
</span>

//Selenium Code
driver.findElement(By.cssSelector("span[data-automation-id='SEL-ERR']"));

If Selenium cannot find it, it’ll throw an exception. Exceptions are costly. You can use .findElements instead (mentioned in 1)), which will simply return an empty list if it cannot find the element you are looking for

driver.findElements(By.cssSelector("span[data-automation-id='SEL-ERR']")).size() != 0;

The below examples are specific to Junit4

<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>

Basic Test case which Fails

import static org.junit.Assert.*;
import org.junit.Test;

public class Junit1 {	
 @Test
 public void basicTestFail()
 {
  fail("The Test Failed");
 }
}

There is No pass method in JUnit like fail method.

As long as the test doesn’t throw an exception, it passes, unless your @Test annotation specifies an expected exception. I suppose a pass() could throw a special exception that JUnit always interprets as passing, so as to short circuit the test, but that would go against the usual design of tests (i.e. assume success and only fail if an assertion fails) and, if people got the idea that it was preferable to use pass(), it would significantly slow down a large suite of passing tests (due to the overhead of exception creation). Failing tests should not be the norm, so it’s not a big deal if they have that overhead.

Tests to verify the correctness of a program’s behavior.Verifying the correctness of a program’s behaviour by inspecting the content of output statements.Its looking manually for abnormal output.

Example1

StringHelper.java

package com.mugil.junit.tutor;

public class StringHelper
{	
	public static void main(String[] args)
	{
		StringHelper objStringHelper = new StringHelper();
		System.out.println(objStringHelper.wordATrimmer("PABBB"));
	}
	
	public String wordATrimmer(String pWord)
	{
  	   String pTempString = pWord.substring(0, 2);			   
           if(pTempString.contains("A")) return pWord.replace("A", "");		
 	   pTempString = pWord.substring(2);		
	   return pWord;
	}
}

StringHelperTest.java

package com.mugil.junit.tutor;

import static org.junit.Assert.*;
import org.junit.Test;

public class StringHelperTest 
{
	@Test
	public void test() 
        {
		StringHelper objStringHelper = new StringHelper();
		String expectedOP            = "MMG";
		String actOP                 = objStringHelper.wordATrimmer("AAMMG");
		
		assertEquals(expectedOP, actOP);
	}
}

@Test comes from org.junit.Test Package
assertEquals – helps in performing String, Boolean and Other Comparison.

As you have seen above StringHelper.java is the actual file that has the function.StringHelperTest.java is the file in which test of the functionality is to be carried out. This java file is created in a new source folder test. By using the assert equals method we are comparing whether the expected Op and actual OP are the same.

@Test annotation at the top of the test method tells the JVM to run this method

assertTrue(boolean)
assertTrue(boolean true) will return true
assertFalse(boolean false) will return true

To make sure the code is behaving the right way we can use asserttrue() and assertfalse() methods.
StringHelper.java

package com.mugil.junit.tutor;

public class StringHelper
{	
	public boolean areFirstTwoandLastTwoStringsSame(String Name)
	{
		if(Name.length() <  2) return false;		
		if(Name.length() == 2) return true;
		
		String firstChars = Name.substring(0, 2);
		String lastChars  = Name.substring(Name.length()-2);
		
		if(firstChars == lastChars)
		  return true;
		else
		  return false;
	}
}

StringHelperTest.java

 package com.mugil.junit.tutor;

import static org.junit.Assert.*;
import org.junit.Test;

public class StringHelperTest 
{
  @Test
  public void test() 
  {
    StringHelper objStringHelper = new StringHelper();
    assertTrue(objStringHelper.areFirstTwoandLastTwoStringsSame("AB"));
    assertFalse(objStringHelper.areFirstTwoandLastTwoStringsSame("ABAB"));
  }
}

The above code checks whether First and Last two characters are the same and return true or false based on input to method areFirstTwoandLastTwoStringsSame.

@Before and @After Annotations
The before and after methods are used to run a case before and after the actual test started.

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class StringHelperTest 
{
	
  @Before
  public void before()
  {	
    System.out.println("Before Test");
  }
	
  @After
  public void after()
  {	
    System.out.println("After Test");
  }

  @Test
  public void test1() 
  {
    System.out.println("Test1");
  }
	
  @Test
  public void test2() 
  {
    System.out.println("Test2");
  }	
}

The output of the above code would be
Output

Before Test
Test1
After Test
Before Test
Test2
After Test

You can also run a test before and after the class run as below

import org.junit.AfterClass;
import org.junit.BeforeClass;

@BeforeClass
public static void beforeClass()
{	
  System.out.println("Before Test");
}
	
@AfterClass
public static void afterClass()
{	
  System.out.println("After Test");
}

@Test
public void test1() 
{
  StringHelper objStringHelper = new StringHelper(); 
  System.out.println("During Test");
}

Output

Before Test
During Test
After Test

BeforeClass and AfterClass is run only once when object for class is created.Note the static before beforeClass and afterClass methods.

Typical Example for Using before and after methods where object for class created in before method and object assigned null in after method.

public class StringHelperTest 
{	
  StringHelper objStringHelper1;
	
  @Before
  public void before()
  {	
     objStringHelper1 = new StringHelper(); 
  }
	
  @After
  public void afterClass()
  {	
    objStringHelper1 = null;
  }

  @Test
  public void test1() 
  {   
    System.out.println("Test Cases");
  }	
}

How to check expected array is returned in Output

 
import static org.junit.Assert.*;
import org.junit.Test;

public class StringHelperTest 
{
  @Test
  public void test1() 
  {
    int[] arrNums1 = {5,4,3,2,1};
    Arrays.sort(arrNums1);		
    int[] arrNums2 = {1,2,3,4,5};
		
    assertArrayEquals(arrNums1, arrNums2);
  }
}

assertArrayEquals method comes from org.junit.Assert Package

We are going to look for the expected exception is getting thrown or not

Testing for Exception

import java.util.Arrays;
import org.junit.Test;

public class StringHelperTest 
{
  @Test(expected=NullPointerException.class)
  public void test1() 
  {
    int[] arrNums1 = null;
    Arrays.sort(arrNums1);
  }
}

Testing for Performance – How Much time is taken by code block to execute the code.

In the below code we are going to estimate actual time taken by the code block to execute

 public class StringHelperTest 
 {
   @Test(timeout=100)
   public void test1() 
   {
     for (int i = 0; i < 1000000; i++) 
     {
	    int[] arrNumbs = {i-1, i, i+1};
          Arrays.sort(arrNumbs);
     }
   }
}

timeout=100 – is going to tell the code should complete the execution within 100 milliseconds.If it fails I should optimize the code by performance tweaks to boost codes performance.