JUnit - SPLessons

JUnit Test Fixture

Chapter 9

SPLessons 5 Steps, 3 Clicks
5 Steps - 3 Clicks

JUnit Test Fixture

JUnit Test Fixture

shape Introduction

This chapter demonstrate the JUnit Test Fixtures. Which has several methods for setting the environment and to develop the test case environment for the designed projects and the following are some of the methods to set up the environment and Test cases for JUnit Test Fixture.

  • Test Fixtures
  • Rules
  • Theories

Test Fixtures

shape Description

JUnit Test Fixture can be used as a base line for running tests. Which is also known as a fixed state of set of objects. JUnit Test Fixture ensure that there is a settled and suitable environment in which tests are performing and executing well known and repeatable results.

For group of tests user need different test fixture instead of this user can create own fixtures and can also create common fixture for same featured group of tests.

shape Examples

The code below demonstrate the fixture called Catalog of products. Each product has sales, quantity and name.

// Catalog class
public class Catalog {
    private String title;
    private Vector products = new Vector();
}
//Product class
public class Product {
    private String name;
   private int quantity;
    private float price;
}

Now user need to create test case for the above created classes.

package junittest;
import junit.framework.*;
public class CatalogTest extends TestCase {
  private Catalog myCatalog;
  private Product aProduct;
  public CatalogTest(String name) {
    super(name);
  }
  protected void setUp() {
    myCatalog = new Catalog();
    aProduct = new Product("Product 1", 5, 25.05);
    myCatalog.addProduct(aProduct);
  }

  protected void tearDown() {
    myCatalog = null;
  }
  public void testProductAdd() {
    int beforeAdd = myCatalog.getItemCount();
    Product newProduct = new Product("Product 2", 4, 14.56);
    myCatalog.addProduct(newProduct);
    assertEquals(beforeAdd+1, myCatalog.getItemCount());
  }
  public void testProductRemoveByName() {
  try {
    int beforeRemove = myCatalog.getItemCount();
    String productNameToRemove = "Product 1";
    myCatalog.removeProductByName(productNameToRemove);
    assertEquals(beforeRemove-1, myCatalog.getItemCount());

    } catch(ProductNotFoundException failure) {
      fail("Should never raise a ProductNotFoundException");
    }
  }
  public void testProductRemove() {
  try {
    int beforeRemove = myCatalog.getItemCount();
    Product producttoRemove = new Product(aProduct);
    myCatalog.removeProduct(producttoRemove);
    assertEquals(beforeRemove-1, myCatalog.getItemCount());

    } catch(ProductNotFoundException failure) {
      fail("Should never raise a ProductNotFoundException");
    }
  }
  public void testClear() {
    myCatalog.clear();
    assertTrue(myCatalog.isEmpty());
  }

  public void testProductNotFound() {
    try {
      Product naProduct = new Product("Product NA", 2, 5.65);
      myCatalog.removeProduct(naProduct);
      fail("Should raise a ProductNotFoundException");

    } catch(ProductNotFoundException success) {
    }
  }
  public static Test suite(String[] args) {
     if (args.length == 0){
       return new TestSuite(CatalogTest.class);
     }
     else{
       TestSuite testsToRun = new TestSuite();
       for (int i = 0; i<args.length; i++){
        testsToRun.addTest(new CatalogTest(args[i]));
       }
       return testsToRun;
     }
  }
public static void main(String args[]) throws ClassNotFoundException{
   junit.textui.TestRunner.run(suite(args));
   return;
 }
}

The below image indicates the output for the above program.

Rules

shape Description

JUnit has many more built in rules and user can also create own rules those are useful in extending the JUnit itself. Rules are meant to add some functionality before or after running a test.

Whenever user use the rule annotation before and after annotation that goes together. User can create some own rules from the existing rules. Following are some basic rules.


shape Examples

The code below demonstrate the Timeout rule which can apply to the entire class of the program. In which rule first user need to declare it and then called Time out.

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

import com.simpleprogram.proteintracker.TrackingService;
import static org.junit.Assert.*;

public class trackingServiceeTest {
	
	private TrackingService service;
	
	@BeforeClass
	public static void before()
	{
		System.out.println("Before Class");
	}
	@AfterClass
	public static void after()
	{
		System.out.println("After Class");
	}
	@Before
	public void setUp()
	{
		System.out.println("Before");
		service = new TrackingService();
     }
	
	@After
	public void tearDown()
	{
		System.out.println("After");
	}
	
	@Test
	public void NewTrackingServiceTotalIsZero()
	{
		assertEquals("Tracking service was not zero", 0, service.getTotal());
		
	}
        @rule 
        Public Timeout timeout = new Timeout(20);
	@Test (timeout = 200)
		Public void badtest() {
		For int(i=0; i<1000000; i++)
		Service.addprotein(1)

	@Test
	public void WhenAddingProteinTotalIncresesByThatAmount()
	{
		service.addProtein(10);
		assertEquals("Protein amount was not correct", 10, service.getTotal());
	}
	
	@Test
	public void WhenRemovingProteinTotalRemainsZero()
	{
		service.removeProtein(5);
		assertEquals(0, service.getTotal());
	}
}

By running the above code it will be timed out after 20 milliseconds as shown in the below image.

Theories

shape Description

Theories are basically a test that holds true under all conditions and meet a set of assumptions. User can create a theory annotation under instead of test annotation in test method. Theory method which use a single parameter data type that use as a input for the test.

User can set up test data by using the datapoint annotation that either returns single piece of data to test or collection of inputs. Theory annotation are almost same like a Parameterized test but the only difference is theory have the same expected result for all inputs.

shape Examples

The below code demonstrate theory for TrackingService if user pass positive value to add protein the total will always be positive.

import org.junit.experimental.theories.dtatpoints;
import org.junit.experimental.theories.Theories;
import org.junit.experimental.theories.thery;
import org.junit.runner.RunWith;

import static org.junit.Assert.*;

import com.simpleprogrammer.proteintracker.trackningService;

@RunWith(Theories.class)
public class TrackingTheories{

	@DataPoints
	public static int[] data() {
		return new int[] {
				1, 5, 10, 15, 20, 50, -4
		};
		@theory
		public void poistiveValuesShouldAlwaysPositiveTotals(int value){
			TrackingService service = new TrackingService();
			service.addProtein(value);
			
			assertTrue(service.getTotal() &gt; 0;)
		}
	}
		
}

In the above program user gave the negative value but the theory annotation ignored that value and gave the positive results that shown in below image.

Summary

shape Key Points

  • JUnit Test Fixture create suitable environments for the test methods.
  • User can create appropriate rules for the test method.
  • Theories runner allows functionality of test against a subset of infinite set of data points.
  • Fixtures contain setUp and tearDown methods.