JUnit+EasyMock测试实例
2022/3/26 6:53:02
本文主要是介绍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; } }
四、参考文献
Java的匿名内部类
这篇关于JUnit+EasyMock测试实例的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-17getExternalFilesDir这个方法哪些安卓版本可以使用?-icode9专业技术文章分享
- 2024-11-17app下载好后,安装包更新代码怎么写?-icode9专业技术文章分享
- 2024-11-17login-customer-id 如何获取?-icode9专业技术文章分享
- 2024-11-17使用 vite加载.env 文件环境变量无法加载是什么原因?-icode9专业技术文章分享
- 2024-11-17tp钱包是什么,有哪些功能?-icode9专业技术文章分享
- 2024-11-16在电脑上怎么模拟手机的运行环境?-icode9专业技术文章分享
- 2024-11-16接收socket数据,莫名其妙socket就关闭了是怎么回事?-icode9专业技术文章分享
- 2024-11-16ts nightly是什么?-icode9专业技术文章分享
- 2024-11-16如何升级vscode版本?-icode9专业技术文章分享
- 2024-11-16如何设置vscode默认的node版本?-icode9专业技术文章分享