实现代码很简单:
package com.xiaozan.shopping;
import java.util.Arrays;
public class ShoppingCart {
public final static int PRODUCT_1_PRICE = 2000; // 产品编号第一个数字为1的单价,单位(分)
public final static int PRODUCT_2_PRICE = 1000; // 其他产品编号的单价,单位 (分)
public final static int PRODUCT_1_TYPE = 1; // 产品编号第一个数字为1的商品定义为类型1产品
/**
*
* @方法说明 按从小到大排列数组
* @param data
* @return void
*/
public void sort(int[] data) {
Arrays.sort(data);
}
/**
*
* @方法说明 传入已排序的数据,计算数组中产品编号第一个数字为1的个数
* @param data
* @return
* @return int
*/
public int countProduct1(int[] data) {
int product1Sum = 0;
for (int i = 0; i < data.length; i++) {
int theFirstNumber = data[i]/100; // 产品编号的第一个数字
if (theFirstNumber == PRODUCT_1_TYPE) {
// 产品类型1的数量 +1
product1Sum++;
} else {
// 因为已经排序,如果不是产品类型1,则剩余的都不是产品类型1的产品
return product1Sum;
}
}
return product1Sum;
}
/**
*
* @方法说明 计算购物车总金额
* @param data
* @return
* @return int
*/
public int sum(int[] data) {
int sum = 0; // 总金额
sort(data); // 按从小到大排列产品编号
int product1Sum = countProduct1(data); // 类型1产品的个数
sum = (product1Sum / 4) * (PRODUCT_1_PRICE * 3) // 买4件类型1的产品只需付3件的钱
+ (product1Sum % 4) * PRODUCT_1_PRICE // 不足4件类型1的产品按类型1的产品单价结算
+ (data.length - product1Sum) * PRODUCT_2_PRICE; // 其他类型的产品按其他类型单价结算
// 如果折后金额大于等于50元,则全单八折
if (sum >= 5000) {
sum *= 0.8;
}
return sum;
}
}
个人对测试仍不是很熟练,对Junit的一次练手:
package com.xiaozanoa.shopping;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import java.util.Arrays;
import java.util.Collection;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import com.xiaozan.shopping.ShoppingCart;
@RunWith(Parameterized.class)
public class TestShoppingCart {
ShoppingCart shoppingCart = null;
int[] data = null; // 预设购物车购买下产品编号
int[] expectedSort = null; // 预期的排序结果
int expectedSum = 0; // 预期产品总金额
int expectedProduct1Sum = 0; // 预期产品1总数
@Parameters
public static Collection<Object[][]> prepareData() {
Object[][][] objects = {
// 含产品1和其他产品,产品1多于4件,金额大于50
{ {229, 132, 129, 217, 190, 118, 387, 124},
{118, 124, 129, 132, 190, 217, 229, 387}, {5}, {8800} },
// 没有产品1 ,金额小于50
{ {229}, {229}, {0}, {1000} },
// 没有产品1 ,金额等于50
{ {229, 217, 387, 222, 345}, {217, 222, 229, 345, 387}, {0}, {4000} },
// 只有产品1 且少于4件,金额小于50
{ {118}, {118}, {1}, {2000} },
// 只有产品1 且等于4件,金额大于50
{ {129, 190, 118, 124}, {118, 124, 129, 190}, {4}, {4800} },
// 只有产品1 且大于4件,金额大于50
{ {132, 129, 190, 118, 124}, {118, 124, 129, 132, 190}, {5}, {6400} } };
return Arrays.asList(objects); // 将数组转换成集合返回
}
public TestShoppingCart(Object[] _data, Object[] _expectedSort,
Object[] _expectedProduct1Sum, Object[] _expectedSum) {
// 构造方法
// JUnit会使用准备的测试数据传给构造函数
data = new int[_data.length];
expectedSort = new int[_expectedSort.length];
for (int i = 0; i < _data.length; i++) {
data[i] = (Integer) _data[i];
}
for (int i = 0; i < _expectedSort.length; i++) {
expectedSort[i] = (Integer) _expectedSort[i];
}
this.expectedProduct1Sum = (Integer) _expectedProduct1Sum[0];
this.expectedSum = (Integer) _expectedSum[0];
}
@Before
public void setUp() {
shoppingCart = new ShoppingCart();
}
@Test
public void testCountProduct1() {
int result = shoppingCart.countProduct1(expectedSort); //计算产品1的数量是在已排序的数组的基础上计算的
assertEquals(expectedProduct1Sum, result);
}
@Test
public void testSort() {
shoppingCart.sort(data);
assertArrayEquals(expectedSort, data);
}
@Test
public void testSum() {
int result = shoppingCart.sum(data);
assertEquals(expectedSum, result);
}
}
测试覆盖率:
测试时主要遇到的问题在参数化测试。
常规一般见的参数化例子都是单个数字,如:
@Parameters
public static Collection prepareData()
{
// 测试数据
Object[][] objects = { { 3, 1, 2 }, { -4, -1, -3 }, { 5, 2, 3 },{ 4, -4, 8 } };
return Arrays.asList(objects);// 将数组转换成集合返回
}
所以我在做的时候就想当然的仿照着做:
错误1:argument type mismatch
public TestShoppingCart(int[] _data, int[] _expectedSort, int[] _expectedProduct1Sum, int[] _expectedSum) {
……
}
错误2:
Type mismatch: cannot convert from Object[] to int[]
int[] data = null; // 预设购物车购买下产品编号
int[] expectedSort = null; // 预期的排序结果
public TestShoppingCart(Object[] _data, Object[] _expectedSort,
Object[] _expectedProduct1Sum, Object[] _expectedSum) {
……
}
错误3:java.lang.NullPointerException
int[] data = null; // 预设购物车购买下产品编号
int[] expectedSort = null; // 预期的排序结果
原因:没有创建对象
错误4:计算的总额与预期的不一致
int[] data = new int[8]; // 预设购物车购买下产品编号
int[] expectedSort = new int[8]; // 预期的排序结果
错误原因:固定了数组大小为8,不足8位,补0填充,这样放到该代码中就有问题了
一分耕耘一分收获…