<file_sep>package com.mycompany.salestax.dao;

import com.mycompany.salestax.beans.Tax;

public interface TaxDao extends AbstractDao<Tax, Long> {
	
}
<file_sep>package com.mycompany.salestax.dao.hibernate;

import org.springframework.stereotype.Repository;

import com.mycompany.salestax.beans.Tax;
import com.mycompany.salestax.dao.TaxDao;

@Repository(value = "taxDaoHibernate")
public class TaxDaoHibernate extends AbstractDaoHibernate<Tax, Long> implements TaxDao {
	
}
<file_sep>package com.mycompany.salestax.services.impl;

import org.junit.Assert;
import org.springframework.test.util.ReflectionTestUtils;

import com.mycompany.salestax.beans.ProductType;
import com.mycompany.salestax.dao.mock.ProductTypeDaoMock;
import com.mycompany.salestax.services.ProductTypeService;

public class ProductTypeServiceImplTest extends AbstractServiceImplTest<ProductType> {
	
	public ProductTypeServiceImplTest() {
		super();
		ProductTypeService mockService = new ProductTypeServiceImpl();
		ReflectionTestUtils.setField(mockService, "dao", new ProductTypeDaoMock());
		this.service = mockService;
	}
	
	@Override
	protected void hookCheckLoadedObject(ProductType productType) {
		Assert.assertNotNull(productType.getDescription());
		Assert.assertNotNull(productType.getTax());
		Assert.assertNotNull(productType.getId());
	}
	
	@Override
	protected ProductType hookTestObjectModification(ProductType productType) {
		productType.setDescription("another description");
		return productType;
	}
	
	@Override
	protected void hookCheckUpdatedObject(ProductType objectToUpdate, ProductType objectUpdated) {
		Assert.assertEquals(objectToUpdate.getDescription(), objectUpdated.getDescription());
	}
	
}
<file_sep>salestax.hibernate.dialect=org.hibernate.dialect.H2Dialect
salestax.hibernate.show_sql=true
salestax.hibernate.hbm2ddl.auto=validate<file_sep>package com.mycompany.salestax.rest.resources;

import java.util.List;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.mycompany.salestax.beans.Product;
import com.mycompany.salestax.services.ProductService;

@Component
@Path("/products")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class ProductResource {
	
	private final static Logger LOG = LoggerFactory.getLogger(ProductResource.class);
	
	@Autowired
	private ProductService service;
	
	@GET
	public List<Product> getProducts() {
		List<Product> list = service.list();
		LOG.debug("Products list: " + list.toString());
		return list;
	}
}
<file_sep>package com.mycompany.salestax.dao;

import java.io.Serializable;
import java.util.List;

import org.springframework.transaction.annotation.Transactional;

import com.mycompany.salestax.beans.ModelBean;

@Transactional
public interface AbstractDao<T extends ModelBean<ID>, ID extends Serializable> {
	
	T create(T object);
	
	T read(ID id);
	
	void update(T object);
	
	void delete(ID id);
	
	List<T> list();
}
<file_sep>package com.mycompany.salestax.services.impl;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.mycompany.salestax.beans.ImportTax;
import com.mycompany.salestax.dao.ImportTaxDao;
import com.mycompany.salestax.services.ImportTaxService;

@Service("importTaxServiceImpl")
public class ImportTaxServiceImpl extends AbstractServiceImpl<ImportTax, Long> implements ImportTaxService {
	
	@Resource(name = "importTaxDaoHibernate")
	public void setDao(ImportTaxDao importTaxDao) {
		this.dao = importTaxDao;
	}
}
<file_sep>drop table Products if exists
drop table ProductTypes if exists
drop table Taxes if exists
drop table ImportTaxes if exists<file_sep>package com.mycompany.salestax.dao.constants;

public interface ContextPaths {
	
	String HIBERNATE_TEST_CONTEXT = "file:src/main/resources/META-INF/hibernate.xml";
	String MOCK_TEST_CONTEXT = "file:src/test/resources/META-INF/mock-test.xml";
}
<file_sep>package com.mycompany.salestax.services.impl;

import org.junit.Assert;
import org.springframework.test.util.ReflectionTestUtils;

import com.mycompany.salestax.beans.Product;
import com.mycompany.salestax.dao.mock.ProductDaoMock;
import com.mycompany.salestax.services.ProductService;

public class ProductServiceImplTest extends AbstractServiceImplTest<Product> {
	
	public ProductServiceImplTest() {
		super();
		ProductService mockService = new ProductServiceImpl();
		ReflectionTestUtils.setField(mockService, "dao", new ProductDaoMock());
		this.service = mockService;
	}
	
	@Override
	protected void hookCheckLoadedObject(Product product) {
		Assert.assertNotNull(product.getDescription());
		Assert.assertNotNull(product.getImportTax());
		Assert.assertNotNull(product.getPrice());
		Assert.assertNotNull(product.getType());
		Assert.assertNotNull(product.getId());
	}
	
	@Override
	protected Product hookTestObjectModification(Product product) {
		product.setDescription("another description");
		return product;
	}
	
	@Override
	protected void hookCheckUpdatedObject(Product objectToUpdate, Product objectUpdated) {
		Assert.assertEquals(objectToUpdate.getDescription(), objectUpdated.getDescription());
	}
	
}
<file_sep>package com.mycompany.salestax.dao;

import com.mycompany.salestax.beans.ProductType;

public interface ProductTypeDao extends AbstractDao<ProductType, Long> {
	
}
<file_sep>package com.mycompany.salestax.beans;

import java.io.Serializable;
import java.math.BigDecimal;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

import org.apache.commons.lang3.builder.ToStringBuilder;

@Entity
@Table(name = "ImportTaxes")
public class ImportTax implements Serializable, ModelBean<Long> {
	
	private static final long serialVersionUID = -3015161145255023640L;
	private Long id;
	private BigDecimal value;
	private String description;
	
	public ImportTax() {
	}
	
	public ImportTax(String description) {
		this.description = description;
	}
	
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "import_tax_id", unique = true, nullable = false)
	public Long getId() {
		return id;
	}
	
	public void setId(Long id) {
		this.id = id;
	}
	
	@Column(name = "import_tax_value", unique = true, nullable = false, precision = 20, scale = 2)
	public BigDecimal getValue() {
		return value;
	}
	
	public void setValue(BigDecimal value) {
		this.value = value;
	}
	
	@Column(name = "description", unique = true, nullable = false, length = 255)
	public String getDescription() {
		return description;
	}
	
	public void setDescription(String description) {
		this.description = description;
	}
	
	@Override
	public String toString() {
		return ToStringBuilder.reflectionToString(this);
	}
	
	@Override
	public int hashCode() {
		int hash = 6;
		
		hash = 24 * hash + ((getDescription() != null) ? getDescription().hashCode() : 0);
		hash = 24 * hash + ((getValue() != null) ? getValue().hashCode() : 0);
		
		return hash;
	}
	
	@Override
	public boolean equals(Object object) {
		if (!(object instanceof ImportTax))
			return false;
		return (this.getDescription().equals(((ImportTax) object).getDescription())) ? true : false;
	}
}
<file_sep>var productsData, totalPrice = 0, totalSales = 0;
var fill_combo_box = (function() {
    initialize = function() {
		$.ajax({
		    type: 'GET',
		    url: "/salestaxrest/products",
		    contentType: "application/json",
		    dataType: "json",
		    success:  function(data) {  
		    	productsData = data;
		    	var options = $("#products");
		    	options.append($("<option />").val("0").text("Select a product"));
		    	$.each(data, function(info) {
		    	    options.append($("<option />").val(this.productId).text(this.description));
		    	});
	    	}
	    });
    };

    return {
    	initialize : initialize
    };
})();

$(function(){
	fill_combo_box.initialize();
});<file_sep>package com.mycompany.salestax.dao.hibernate;

import javax.annotation.Resource;

import org.springframework.test.context.ContextConfiguration;

import com.mycompany.salestax.beans.ImportTax;
import com.mycompany.salestax.dao.AbstractDao;
import com.mycompany.salestax.dao.ImportTaxDaoTest;
import com.mycompany.salestax.dao.constants.ContextPaths;

@ContextConfiguration(locations = ContextPaths.HIBERNATE_TEST_CONTEXT)
public class ImportTaxDaoHibernateTest extends ImportTaxDaoTest {
	
	@Resource(name = "importTaxDaoHibernate")
	@Override
	protected void setAbstractDao(AbstractDao<ImportTax, Long> importTaxDao) {
		this.abstractDao = importTaxDao;
	}
}
<file_sep>package com.mycompany.salestax.dao;

import com.mycompany.salestax.beans.ImportTax;

public interface ImportTaxDao extends AbstractDao<ImportTax, Long> {
	
}
<file_sep>package com.mycompany.salestax.services.impl;

import java.io.Serializable;
import java.util.List;

import org.springframework.transaction.annotation.Transactional;

import com.mycompany.salestax.beans.ModelBean;
import com.mycompany.salestax.dao.AbstractDao;
import com.mycompany.salestax.services.AbstractService;

@Transactional
public abstract class AbstractServiceImpl<T extends ModelBean<ID>, ID extends Serializable> implements AbstractService<T, ID> {
	
	protected AbstractDao<T, ID> dao;
	
	public T save(T objectToSave) {
		return dao.create(objectToSave);
	}
	
	public T load(ID id) {
		return dao.read(id);
	}
	
	public void update(T objectToUdpate) {
		dao.update(objectToUdpate);
	}
	
	public void remove(ID id) {
		dao.delete(id);
	}
	
	public List<T> list() {
		return dao.list();
	}
}
<file_sep>package com.mycompany.salestax.util;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.RandomStringUtils;

import com.mycompany.salestax.beans.ImportTax;
import com.mycompany.salestax.beans.ModelBean;
import com.mycompany.salestax.beans.Product;
import com.mycompany.salestax.beans.ProductType;
import com.mycompany.salestax.beans.Tax;

public abstract class MockBeanFactory {
	
	@SuppressWarnings("unchecked")
	public static <T extends ModelBean<Long>> T getMock(Class<T> beanClass) {
		
		if (beanClass.equals(Product.class)) {
			return (T) getProductMock();
		} else if (beanClass.equals(ProductType.class)) {
			return (T) getProductTypeMock();
		} else if (beanClass.equals(Tax.class)) {
			return (T) getTaxMock();
		} else if (beanClass.equals(ImportTax.class)) {
			return (T) getImportTaxMock();
		}
		return null;
	}
	
	public static <T extends ModelBean<Long>> List<T> getListMock(Class<T> beanClass, int length) {
		List<T> list = new ArrayList<T>();
		for (int i = 0; i < length; i++) {
			list.add(getMock(beanClass));
		}
		return list;
	}
	
	private static ImportTax getImportTaxMock() {
		ImportTax importTax = new ImportTax();
		importTax.setDescription("description" + getRandomValue());
		importTax.setValue(new BigDecimal(300));
		return importTax;
	}
	
	private static Tax getTaxMock() {
		Tax tax = new Tax();
		tax.setDescription("description" + getRandomValue());
		tax.setValue(new BigDecimal(200));
		return tax;
	}
	
	private static ProductType getProductTypeMock() {
		ProductType productType = new ProductType();
		productType.setDescription("description" + getRandomValue());
		productType.setTax((Tax) getTaxMock());
		productType.getTax().setId(1l);
		return productType;
	}
	
	private static Product getProductMock() {
		Product product = new Product();
		product.setDescription("description" + getRandomValue());
		product.setImportTax((ImportTax) getImportTaxMock());
		product.getImportTax().setId(1l);
		product.setPrice(new BigDecimal(100));
		product.setType((ProductType) getProductTypeMock());
		product.getType().setId(1l);
		return product;
	}
	
	private static String getRandomValue() {
		return RandomStringUtils.random(100);
	}
}
<file_sep>package com.mycompany.salestax.services.impl;

import org.junit.Assert;
import org.springframework.test.util.ReflectionTestUtils;

import com.mycompany.salestax.beans.Tax;
import com.mycompany.salestax.dao.mock.TaxDaoMock;
import com.mycompany.salestax.services.TaxService;

public class TaxServiceImplTest extends AbstractServiceImplTest<Tax> {
	
	public TaxServiceImplTest() {
		super();
		TaxService mockService = new TaxServiceImpl();
		ReflectionTestUtils.setField(mockService, "dao", new TaxDaoMock());
		this.service = mockService;
	}
	
	@Override
	protected void hookCheckLoadedObject(Tax tax) {
		Assert.assertNotNull(tax.getDescription());
		Assert.assertNotNull(tax.getValue());
		Assert.assertNotNull(tax.getId());
	}
	
	@Override
	protected Tax hookTestObjectModification(Tax tax) {
		tax.setDescription("another description");
		return tax;
	}
	
	@Override
	protected void hookCheckUpdatedObject(Tax objectToUpdate, Tax objectUpdated) {
		Assert.assertEquals(objectToUpdate.getDescription(), objectUpdated.getDescription());
	}
}
<file_sep>salestax.script.inicializacion=classpath*:META-INF/salestax.h2.init.sql
salestax.script.finalizacion=classpath*:META-INF/salestax.h2.destroy.sql
salestax.script.datos=classpath*:META-INF/salestax.data.sql
<file_sep>package com.mycompany.salestax.dao.mock;

import javax.annotation.Resource;

import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;

import com.mycompany.salestax.beans.Tax;
import com.mycompany.salestax.dao.AbstractDao;
import com.mycompany.salestax.dao.TaxDaoTest;
import com.mycompany.salestax.dao.constants.ContextPaths;

@ContextConfiguration(locations = ContextPaths.MOCK_TEST_CONTEXT)
@TestExecutionListeners(DependencyInjectionTestExecutionListener.class)
public class TaxDaoMockTest extends TaxDaoTest {
	
	@Resource(name = "taxDaoMock")
	@Override
	protected void setAbstractDao(AbstractDao<Tax, Long> taxDao) {
		this.abstractDao = taxDao;
	}
	
}
<file_sep>package com.mycompany.salestax.services.impl;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.mycompany.salestax.beans.ProductType;
import com.mycompany.salestax.dao.ProductTypeDao;
import com.mycompany.salestax.services.ProductTypeService;

@Service("productTypeServiceImpl")
public class ProductTypeServiceImpl extends AbstractServiceImpl<ProductType, Long> implements ProductTypeService {
	
	@Resource(name = "productTypeDaoHibernate")
	public void setDao(ProductTypeDao productTypeDao) {
		this.dao = productTypeDao;
	}
}
<file_sep>package com.mycompany.salestax.services.impl;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.mycompany.salestax.beans.Product;
import com.mycompany.salestax.dao.ProductDao;
import com.mycompany.salestax.services.ProductService;

@Service("productServiceImpl")
public class ProductServiceImpl extends AbstractServiceImpl<Product, Long> implements ProductService {
	
	@Resource(name = "productDaoHibernate")
	public void setDao(ProductDao productDao) {
		this.dao = productDao;
	}
	
}
<file_sep>package com.mycompany.salestax.dao.hibernate;

import javax.annotation.Resource;

import org.springframework.test.context.ContextConfiguration;

import com.mycompany.salestax.beans.Tax;
import com.mycompany.salestax.dao.AbstractDao;
import com.mycompany.salestax.dao.TaxDaoTest;
import com.mycompany.salestax.dao.constants.ContextPaths;

@ContextConfiguration(locations = ContextPaths.HIBERNATE_TEST_CONTEXT)
public class TaxDaoHibernateTest extends TaxDaoTest {
	
	@Resource(name = "taxDaoHibernate")
	@Override
	protected void setAbstractDao(AbstractDao<Tax, Long> productDao) {
		this.abstractDao = productDao;
	}
}
