JUnit+EasyMock测试实例
作者:互联网
JUnit+EasyMock测试实例
一、实例一(纯Java)
要求:
编写一个简单的货币基金选择器,考虑以下几种货币类型:CNY(人民币)、USD(美元)、GBP(英镑)、EUR(欧元)、CAD(加元),假设基金选择方法每次选择兑换值最高的货币作为投资目标,实验包括对JUnit和EasyMock的使用,最后给出关键的代码截图和测试用例运行结果。
1.1 接口 ExchangeRate
import java.io.IOException;
public interface ExchangeRate {
public double getRate(String inputCurrency, String outputCurrency) throws IOException;
}
1.2 需测试类 Currency.java
import java.io.IOException;
public class Currency {
private String unit;
private long amount;
private int cents;
public Currency(double amount,String unit){
this.unit=unit;
setAmount(amount);
}
public void setAmount(double amount2) {
this.amount = new Double(amount2).longValue();
this.cents=(int) amount2*100%100;
}
public Currency toChange(ExchangeRate converter){
String[]u={"CNY","USD","GBP","EUR","CAD"};
String changeUnit=null;
double maxRate=0;
double temp;
try{
for(String tempUnit:u){
temp=converter.getRate(this.unit,tempUnit);
if(temp>maxRate) {
changeUnit=tempUnit;
maxRate=temp;
}
}
if(changeUnit.equals(this.unit)) return this;
double input = amount+cents/100.0;
return new Currency(input*maxRate,changeUnit);
}catch (IOException e) {
e.printStackTrace();
return null;
}
}
public boolean equals(Object o){
if(o instanceof Currency){
Currency other =(Currency) o;
return this.unit.equals(other.unit) && this.amount==other.amount && this.cents==other.cents;
}
return false;
}
public String toString(){
return this.amount+"."+cents+" "+unit;
}
}
1.3 测试类
import junit.framework.TestCase;
import org.easymock.EasyMock;
import org.junit.Test;
import java.io.IOException;
public class CurrencyTest extends TestCase {
@Test
public void test() throws IOException {
Currency testObject=new Currency(2.5,"USD");
Currency expected=new Currency(3.75,"EUR");
ExchangeRate mockRate= EasyMock.createMock(ExchangeRate.class);
EasyMock.expect(mockRate.getRate("USD","USD")).andReturn(1.0);
EasyMock.expect(mockRate.getRate("USD","CNY")).andReturn(0.5);
EasyMock.expect(mockRate.getRate("USD","GBP")).andReturn(1.1);
EasyMock.expect(mockRate.getRate("USD","EUR")).andReturn(1.5);
EasyMock.expect(mockRate.getRate("USD","CAD")).andReturn(0.3);
EasyMock.replay(mockRate);
Currency actual=testObject.toChange(mockRate);
assertEquals(actual,expected);
}
}
{% note warning %}
- Currency类中要覆盖Object的toString方法,是因为assertEquals方法中传入的是两个Currency对象,它会像根据Object的toString方法,将二者转化为String类型,再通过equals方法比较。默认转化为Currency对象的地址。
- Currency类中要覆盖Object的equals方法,是因为Object的equals方法默认按地址比较,而不是内容。
{% endnote %}
二、实例二 (模拟JavaEE环境)
2.1 需测试类 LoginServlet.java
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException{
String username = req.getParameter("username");
String password = req.getParameter("password");
if("admin".equals(username) && "123456".equals(password)) {
ServletContext context = getServletContext();
RequestDispatcher dispatcher = context.getNamedDispatcher("dispatcher");
dispatcher.forward(req, res);
}else {
throw new RuntimeException("Login failed.");
}
}
}
2.2 测试类 TestLoginServlet.java
import junit.framework.TestCase;
import org.easymock.EasyMock;
import org.junit.Before;
import org.junit.Test;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
public class TestLoginServlet extends TestCase {
private HttpServletRequest request;
private ServletContext context;
private RequestDispatcher dispatcher;
private LoginServlet loginServlet;
@Before
public void setUp() throws Exception {
request= EasyMock.createMock(HttpServletRequest.class);
context=EasyMock.createMock(ServletContext.class);
dispatcher=EasyMock.createMock(RequestDispatcher.class);
loginServlet=new LoginServlet();
}
@Test
public void testLoginSuccess() throws Exception{
EasyMock.expect(request.getParameter("username")).andReturn("admin");
EasyMock.expect(request.getParameter("password")).andReturn("123456");
EasyMock.expect(context.getNamedDispatcher("dispatcher")).andReturn(dispatcher);
dispatcher.forward(request,null);
EasyMock.replay(request);
EasyMock.replay(context);
EasyMock.replay(dispatcher);
//匿名类
loginServlet =new LoginServlet(){
public ServletContext getServletContext(){
return context;
}
};
loginServlet.doPost(request,null);
EasyMock.verify(request);
EasyMock.verify(context);
EasyMock.verify(dispatcher);
}
@Test
public void testLoginFailed1() {
EasyMock.expect(request.getParameter("username")).andReturn("ad");
EasyMock.expect(request.getParameter("password")).andReturn("123456");
EasyMock.replay(request);
try {
loginServlet.doPost(request,null);
} catch (Exception e) {
assertEquals("Login failed.",e.getMessage());
}
EasyMock.verify(request);
}
@Test
public void testLoginFailed2() {
EasyMock.expect(request.getParameter("username")).andReturn("admin");
EasyMock.expect(request.getParameter("password")).andReturn("123");
EasyMock.replay(request);
try {
loginServlet.doPost(request,null);
} catch (Exception e) {
assertEquals("Login failed.",e.getMessage());
}
EasyMock.verify(request);
}
@Test
public void testLoginFailed3() {
EasyMock.expect(request.getParameter("username")).andReturn(null);
EasyMock.expect(request.getParameter("password")).andReturn("123456");
EasyMock.replay(request);
try {
loginServlet.doPost(request,null);
} catch (Exception e) {
assertEquals("Login failed.",e.getMessage());
}
EasyMock.verify(request);
}
@Test
public void testLoginFailed4() {
EasyMock.expect(request.getParameter("username")).andReturn("admin");
EasyMock.expect(request.getParameter("password")).andReturn(null);
EasyMock.replay(request);
try {
loginServlet.doPost(request,null);
} catch (Exception e) {
assertEquals("Login failed.",e.getMessage());
}
EasyMock.verify(request);
}
}
{% note warning %}
测试类中之所以用到匿名类,是因为要测试的代码中使用了getServletContext()方法,此方法是Servlet上下文的方法,此处模拟了环境,也应模拟此方法。
How使用匿名类?Java的匿名内部类
{% endnote %}
三、实例三
3.1 接口 DBUtility.java
package org.easymock.demo.domain;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
public interface DBUtility {
public abstract Connection getConnection();
public abstract void closeDBResource(Connection conn);
public abstract void closeDBResource(Statement stmt);
public abstract void closeDBResource(ResultSet rs);
}
3.2 SalesOrders.java
package org.easymock.demo.domain;
import java.sql.ResultSet;
import java.sql.SQLException;
public interface SalesOrder {
public String getOrderNumber();
public String getRegion();
public double getTotalPrice();
public void setOrderNumber(String orderNumber);
public void setRegion(String region);
public void setTotalPrice(double totalPrice);
public void loadDataFromDB(ResultSet resultSet) throws SQLException;
public String getPriceLevel();
public String toString();
}
3.3 SalesOrderImpl.java
package org.easymock.demo.domain;
import java.sql.ResultSet;
import java.sql.SQLException;
public class SalesOrderImpl implements SalesOrder {
private String orderNumber;
private String region;
private double totalPrice;
public String getOrderNumber(){return orderNumber;}
public String getRegion(){return region;}
public double getTotalPrice(){return totalPrice;}
public void setOrderNumber(String orderNumber){this.orderNumber = orderNumber;}
public void setRegion(String region){this.region = region;}
public void setTotalPrice(double totalPrice){this.totalPrice = totalPrice;}
public void loadDataFromDB(ResultSet resultSet) throws SQLException {
orderNumber = resultSet.getString(1);
region = resultSet.getString(2);
totalPrice = resultSet.getDouble(3);
}
public String getPriceLevel() {
double totalPrice = this.getTotalPrice();
double totalPoints = 0.0;
if ("Africa".equalsIgnoreCase(this.getRegion()))
totalPoints = totalPrice;
else if ("Asia Pacific".equalsIgnoreCase(this.getRegion()))
totalPoints = totalPrice * 0.9;
else if ("Europe".equalsIgnoreCase(this.getRegion()))
totalPoints = totalPrice * 0.85;
else if ("America".equalsIgnoreCase(this.getRegion()))
totalPoints = totalPrice * 0.8;
else
totalPoints = totalPrice * 0.75;
if (totalPoints < 500)
return "Level_A";
else if (totalPoints < 1000)
return "Level_B";
else if (totalPoints < 2000)
return "Level_C";
else if (totalPoints < 4000)
return "Level_D";
else
return "Level_E";
}
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("orderNumber = "+orderNumber+"\n");
sb.append("region = "+region+"\n");
sb.append("totalPrice = "+totalPrice+"\n");
sb.append("priceLevel = "+this.getPriceLevel()+"\n");
return sb.toString();
}
}
3.4 测试 SalesOrderTestCase.java
package org.easymock.demo.testcase;
import static org.easymock.EasyMock.expectLastCall;
import static org.easymock.demo.matcher.SQLEquals.sqlEquals;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import junit.framework.TestCase;
import org.easymock.EasyMock;
import org.easymock.IMocksControl;
import org.easymock.demo.domain.DBUtility;
import org.easymock.demo.domain.SalesOrder;
import org.easymock.demo.domain.SalesOrderImpl;
public class SalesOrderTestCase extends TestCase {
public void testSalesOrder() {
IMocksControl control = EasyMock.createControl();
DBUtility mockDBUtility = control.createMock(DBUtility.class);
Connection mockConnection = control.createMock(Connection.class);
Statement mockStatement = control.createMock(Statement.class);
ResultSet mockResultSet = control.createMock(ResultSet.class);
try {
mockDBUtility.getConnection();
EasyMock.expectLastCall().andStubReturn(mockConnection);
mockConnection.createStatement();
expectLastCall().andStubReturn(mockStatement);
mockStatement.executeQuery(sqlEquals("SELECT * FROM sales_order_table"));
expectLastCall().andStubReturn(mockResultSet);
mockResultSet.next();
expectLastCall().andReturn(true).times(3);
expectLastCall().andReturn(false).times(1);
mockResultSet.getString(1);
expectLastCall().andReturn("DEMO_ORDER_001").times(1);
expectLastCall().andReturn("DEMO_ORDER_002").times(1);
expectLastCall().andReturn("DEMO_ORDER_003").times(1);
mockResultSet.getString(2);
expectLastCall().andReturn("Asia Pacific").times(1);
expectLastCall().andReturn("Europe").times(1);
expectLastCall().andReturn("America").times(1);
mockResultSet.getDouble(3);
expectLastCall().andReturn(350.0).times(1);
expectLastCall().andReturn(1350.0).times(1);
expectLastCall().andReturn(5350.0).times(1);
control.replay();
Connection conn = mockDBUtility.getConnection();
Statement stat = conn.createStatement();
ResultSet rs = stat.executeQuery("select * from sales_order_table");
int i = 0;
String[] priceLevels = { "Level_A", "Level_C", "Level_E" };
while (rs.next()) {
SalesOrder order = new SalesOrderImpl();
order.loadDataFromDB(rs);
assertEquals(order.getPriceLevel(), priceLevels[i]);
i++;
}
control.verify();
} catch (Exception e) {
e.printStackTrace();
}
}
}
3.5 自定义参数匹配器 SQLEquals.java
package org.easymock.demo.matcher;
import static org.easymock.EasyMock.reportMatcher;
import org.easymock.IArgumentMatcher;
public class SQLEquals implements IArgumentMatcher {
private String expectedSQL = null;
public SQLEquals(String expectedSQL) {
this.expectedSQL = expectedSQL;
}
public void appendTo(StringBuffer buffer) {
buffer.append("SQLEquals(\"" + expectedSQL + "\")");
}
public boolean matches(Object actualSQL) {
if (actualSQL == null && expectedSQL == null) return true;
else if (actualSQL instanceof String) return expectedSQL.equalsIgnoreCase((String) actualSQL);
else return false;
}
public static String sqlEquals(String in) {
reportMatcher(new SQLEquals(in));
return in;
}
}
四、参考文献
标签:String,EasyMock,request,public,实例,andReturn,import,JUnit 来源: https://www.cnblogs.com/angelia-wang/p/16057559.html