在Salesforce中编写Unit Test
Unit Test 也是一个 Class 文件,所以在创建 Unit Test 的时候要选择 Test Class 类型来创建,请看如下截图(在Eclipse中):
编写 Unit Test 基本流程为:
1):创建模拟数据。
2):调用Test.startTest方法。
3):调用对应的我们所测试的方法。
4):调用Test.stopTest()方法。
测试代码段一般会涉及到:测试属性,测试公共方法,测试静态方法,测试trigger。 请看如下代码段:
@isTest(SeeAllData = true) private class EricSunUtilityTest { static testMethod void myUnitTest() { // first - what user profile are they? Sales Rep Profile p = [select id from Profile where Name = 'Sales Rep' limit 1]; system.assert(p.id != null); User u = [select id, territory__c from User where ProfileId =:p.id and IsActive = true and territory__c != null limit 1]; system.assert(u.id != null); //**--------- create test data ---------------------**// // create test data Account a1 = new Account(); a1.Name = 'Test Account001'; a1.BDM_Owner__c = u.id; a1.Type = 'Prospect'; insert a1; system.assert(a1.id != null); EricSunObject__c object1 = new EricSunObject__c(); object1.Name = 'Test Object001'; object1.OwnerId = u.id; object1.MyDate = date.newinstance(2011,7,1); system.runAs(u){ Test.startTest(); Test.setCurrentPage(Page.EricSunPage); //set which page EricSunController con = new EricSunController(); //init the integer year = EricSunController.thisYear; //test public variable //test special account owner ApexPages.currentPage().getParameters().put('uId',u.id); //set the parameter con.ChangeOwner(); //test public function EricSunController.MyBillins_Target_All(u.id); //test static function (Visualforce.remoting.Manager.invokeAction --> Remote Action) insert object1; system.assert(object1.id != null); //test trigger about EricSunObject__c (insert) Test.stopTest(); } } }
编写完测试代码后,如何进行测试代码运行呢?请看如下过程:
Developer Console --- Test --- New Run --- (Run Your Selected Test)
运行完之后,我们可以在 File --- Open 中选择对应的所测试的文件,来查看Unit Test 的覆盖率。
或者直接在Eclipse中运行对应的Class并且查看结果
Run Test 如下图所示:
View Result 如下图所示:
更加具体的细节,请详看如下链接:
http://wiki.developerforce.com/page/An_Introduction_to_Apex_Code_Test_Methods
这里在简单的介绍一下 system.assert 的用法:
System.assert ---> 如果条件不满足将会抛出异常,通常我们不会在Trigger和Apex class中用到,但是在对应的Test中使用此方法是一个很好的处理方式
如何对 Generate From WSDL 所生成的 Apex Class 进行Unit Test
1):Web Service 所对应的Class
//Generated by wsdl2apex public class ITVDataFeedService { public class ArrayOfNV { public ITVDataFeedService.NV[] NV; ','-1','true'}; private String[] apex_schema_type_info = new String[]{'http://www.itvisions.com.au/ITVisions.WebServices/','true','false'}; private String[] field_order_type_info = new String[]{'NV'}; } public class ArrayOfFilterInfo { public ITVDataFeedService.FilterInfo[] FilterInfo; ','-1','true'}; private String[] apex_schema_type_info = new String[]{'http://www.itvisions.com.au/ITVisions.WebServices/','true','false'}; private String[] field_order_type_info = new String[]{'FilterInfo'}; } public class Feed_element { public String FeedName; public ITVDataFeedService.ArrayOfFilterInfo Filters; public DateTime ChangedAfter; ','false'}; ','false'}; ','true'}; private String[] apex_schema_type_info = new String[]{'http://www.itvisions.com.au/ITVisions.WebServices/','true','false'}; private String[] field_order_type_info = new String[]{'FeedName','Filters','ChangedAfter'}; } public class NV { public String N; public String V; private String[] N_att_info = new String[]{'N'}; private String[] V_att_info = new String[]{'V'}; private String[] apex_schema_type_info = new String[]{'http://www.itvisions.com.au/ITVisions.WebServices/','true','false'}; private String[] field_order_type_info = new String[]{}; } public class ArrayOfArrayOfNV { public ITVDataFeedService.ArrayOfNV[] ArrayOfNV; ','-1','true'}; private String[] apex_schema_type_info = new String[]{'http://www.itvisions.com.au/ITVisions.WebServices/','true','false'}; private String[] field_order_type_info = new String[]{'ArrayOfNV'}; } public class ArrayOfString { public String[] string_x; ','-1','true'}; private String[] apex_schema_type_info = new String[]{'http://www.itvisions.com.au/ITVisions.WebServices/','true','false'}; private String[] field_order_type_info = new String[]{'string_x'}; } public class FeedResponse_element { public ITVDataFeedService.ArrayOfArrayOfNV FeedResult; ','false'}; private String[] apex_schema_type_info = new String[]{'http://www.itvisions.com.au/ITVisions.WebServices/','true','false'}; private String[] field_order_type_info = new String[]{'FeedResult'}; } public class FilterInfo { public String Name; public ITVDataFeedService.ArrayOfString Values; ','false'}; ','false'}; private String[] apex_schema_type_info = new String[]{'http://www.itvisions.com.au/ITVisions.WebServices/','true','false'}; private String[] field_order_type_info = new String[]{'Name','Values'}; } public class DataFeedSoap { public String endpoint_x = 'https://corp-services.jbhifi.com.au/ITVisions.Webservices/DataFeed.asmx'; public Map<String,String> inputHttpHeaders_x; public Map<String,String> outputHttpHeaders_x; public String clientCertName_x; public String clientCert_x; public String clientCertPasswd_x; public Integer timeout_x; private String[] ns_map_type_info = new String[]{'http://www.itvisions.com.au/ITVisions.WebServices/', 'ITVDataFeedService'}; public ITVDataFeedService.ArrayOfArrayOfNV Feed(String FeedName,ITVDataFeedService.ArrayOfFilterInfo Filters,DateTime ChangedAfter) { ITVDataFeedService.Feed_element request_x = new ITVDataFeedService.Feed_element(); request_x.FeedName = FeedName; request_x.Filters = Filters; request_x.ChangedAfter = ChangedAfter; ITVDataFeedService.FeedResponse_element response_x; Map<String, ITVDataFeedService.FeedResponse_element> response_map_x = new Map<String, ITVDataFeedService.FeedResponse_element>(); response_map_x.put('response_x', response_x); WebServiceCallout.invoke( this, request_x, response_map_x, new String[]{endpoint_x, 'http://www.itvisions.com.au/ITVisions.WebServices/Feed', 'http://www.itvisions.com.au/ITVisions.WebServices/', 'Feed', 'http://www.itvisions.com.au/ITVisions.WebServices/', 'FeedResponse', 'ITVDataFeedService.FeedResponse_element'} ); response_x = response_map_x.get('response_x'); return response_x.FeedResult; } } }
2):Unit Test
@isTest private with sharing class ITVDataFeedServiceTest { static testMethod void coverTypes() { // query for a test user User u = []; system.assert(u.id != null); // run test as current test user system.runAs(u){ // start test Test.startTest(); // cover inner class new ITVDataFeedService.ArrayOfNV(); new ITVDataFeedService.ArrayOfFilterInfo(); new ITVDataFeedService.Feed_element(); new ITVDataFeedService.NV(); new ITVDataFeedService.ArrayOfArrayOfNV(); new ITVDataFeedService.ArrayOfString(); new ITVDataFeedService.FeedResponse_element(); new ITVDataFeedService.FilterInfo(); new ITVDataFeedService.DataFeedSoap(); // end test Test.stopTest(); } } static testMethod void coverMethods() { // query for a test user User u = []; system.assert(u.id != null); // run test as current test user system.runAs(u){ // start test Test.startTest(); // cover method new ITVDataFeedService.DataFeedSoap().Feed(null, null, null); // end test Test.stopTest(); } } private class WebServiceMockImpl implements WebServiceMock { public void doInvoke( Object stub, Object request, Map<String, Object> response, String endpoint, String soapAction, String requestName, String responseNS, String responseName, String responseType) { if(request instanceof ITVDataFeedService.Feed_element) response.put('response_x', new ITVDataFeedService.FeedResponse_element()); return; } } }
如何对调用 Web Service 中某些方法的 Apex Class 进行 Unit Test
1):调用Web Service的Apex Class
public class CreditLimitController { //added an instance varaible for the standard controller private ApexPages.StandardController controller {get; set;} // the actual account private Account a; public CreditLimitInfo creLimitInfo {get; set;} private string feedName = 'CustomerCredit'; private string filterInfoName = 'CustomerID'; private ITVDataFeedService itvDFService = new ITVDataFeedService(); private ITVDataFeedService.DataFeedSoap dfSoap = new ITVDataFeedService.DataFeedSoap(); private ITVDataFeedService.FilterInfo fInfo = new ITVDataFeedService.FilterInfo(); private ITVDataFeedService.ArrayOfFilterInfo filterInfoArray = new ITVDataFeedService.ArrayOfFilterInfo(); private ITVDataFeedService.ArrayOfString sArray = new ITVDataFeedService.ArrayOfString(); public CreditLimitController(ApexPages.StandardController controller) { //initialize the stanrdard controller this.controller = controller; this.a = (Account)controller.getRecord(); this.creLimitInfo = getCreditLimitInfo(this.a); } public CreditLimitInfo getCreditLimitInfo(Account acc) { // call web service to get the credit limit by account id fInfo.Name = filterInfoName; string customerId = getCustomerId(acc); string[] sArr = new string[] { customerId }; sArray.string_x = sArr; fInfo.Values = sArray; filterInfoArray.FilterInfo = new ITVDataFeedService.FilterInfo[] {fInfo}; ITVDataFeedService.ArrayOfArrayOfNV nvArrayArray = dfSoap.Feed(feedName, filterInfoArray, DateTime.now()); CreditLimitInfo currentCreditLimitInfo = new CreditLimitInfo(); if(nvArrayArray != null && nvArrayArray.ArrayOfNV != null){ for(ITVDataFeedService.ArrayOfNV aNv : nvArrayArray.ArrayOfNV){ for(ITVDataFeedService.NV nv : aNv.NV){ if(nv.N == 'CustomerID'){ currentCreditLimitInfo.CustomerId = nv.V; } else if(nv.N == 'CreditLimit'){ currentCreditLimitInfo.CreditLimit = Decimal.valueOf(nv.V); } else if(nv.N == 'AvailableCredit'){ currentCreditLimitInfo.AvailableCredit = Decimal.valueOf(nv.V); } else if(nv.N == 'Balance'){ currentCreditLimitInfo.Balance = Decimal.valueOf(nv.V); } } } } return currentCreditLimitInfo; } private string getCustomerId(Account acc){ string customerId = ''; if(acc != null && acc.Id != null){ List<Account> accList = [Select AccountNumber From Account Where Id =: acc.Id]; ){ customerId = accList[].AccountNumber; } } return customerId; } public class CreditLimitInfo { public string CustomerId {get;set;} public decimal CreditLimit {get;set;} public decimal AvailableCredit {get;set;} public decimal Balance {get;set;} public CreditLimitInfo(){ CustomerId = ''; CreditLimit = ; AvailableCredit = ; Balance = ; } public CreditLimitInfo(string cusId, decimal creLimit, decimal avaCredit, decimal bal){ CustomerId = cusId; CreditLimit = creLimit; AvailableCredit = avaCredit; Balance = bal; } } }
2):Unit Test
@isTest private class CreditLimitControllerTest { static testMethod void myUnitTest() { // query for a test user User u = []; system.assert(u.id != null); // insert test data Account account001 = new Account( Name = 'Test Account 0101', AccountNumber = 'IN1200047', Credit_Type__c = 'Account' ); insert account001; system.assert(account001.id != null); // run test as current test user system.runAs(u){ // start test Test.startTest(); // This causes a fake response to be generated Test.setMock(WebServiceMock.class, new WebServiceMockImpl()); Test.setCurrentPage(Page.CreditLimit); ApexPages.StandardController sc = new ApexPages.StandardController(account001); CreditLimitController con = new CreditLimitController(sc); // test the constructor contains multiple parameters CreditLimitController.CreditLimitInfo testCLI = ', 1111.00, 1111.00, 1111.00); // end test Test.stopTest(); } } private class WebServiceMockImpl implements WebServiceMock { public void doInvoke( Object stub, Object request, Map<String, Object> response, String endpoint, String soapAction, String requestName, String responseNS, String responseName, String responseType) { if(request instanceof ITVDataFeedService.Feed_element){ // generate the fake data to test ITVDataFeedService.FeedResponse_element feedRes = new ITVDataFeedService.FeedResponse_element(); ITVDataFeedService.ArrayOfArrayOfNV aaOfNV = new ITVDataFeedService.ArrayOfArrayOfNV(); ITVDataFeedService.ArrayOfNV aOfNV = new ITVDataFeedService.ArrayOfNV(); ITVDataFeedService.NV nvCustomerID = new ITVDataFeedService.NV(); nvCustomerID.N = 'CustomerID'; nvCustomerID.V = 'IN1200047'; ITVDataFeedService.NV nvCreditLimit = new ITVDataFeedService.NV(); nvCreditLimit.N = 'CreditLimit'; nvCreditLimit.V = '1000.11'; ITVDataFeedService.NV nvAvailableCredit = new ITVDataFeedService.NV(); nvAvailableCredit.N = 'AvailableCredit'; nvAvailableCredit.V = '1000.11'; ITVDataFeedService.NV nvBalance = new ITVDataFeedService.NV(); nvBalance.N = 'Balance'; nvBalance.V = '1000.11'; ITVDataFeedService.NV[] nvArray = new ITVDataFeedService.NV[] { nvCustomerID, nvCreditLimit, nvAvailableCredit, nvBalance }; aOfNV.NV = nvArray; ITVDataFeedService.ArrayOfNV[] aOfNVArray = new ITVDataFeedService.ArrayOfNV[] { aOfNV }; aaOfNV.ArrayOfNV = aOfNVArray; feedRes.FeedResult = aaOfNV; // set the fake data to response response.put('response_x', feedRes); } } } }
更多详细信息请看如下链接:
http://andyinthecloud.com/2013/05/11/code-coverage-for-wsdl2apex-generated-classes/
http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_callouts_wsdl2apex_testing.htm
如何对Salesforce提供的Restful Service所对应的Apex Class 进行 Unit Test, 请看如下链接:
http://salesforce.stackexchange.com/questions/4988/writing-test-classes-for-apex-restservice
还有一种偷懒的方式 请看: http://sfdc.arrowpointe.com/2009/05/01/testing-http-callouts/
如何对调用External Restful Service的Apex Class 进行 Unit Test, 请看如下链接:
http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_classes_restful_http_testing_httpcalloutmock.htm
在Salesforce中编写Unit Test的更多相关文章
- 在Salesforce中以PDF的格式显示对应的页面
在Salesforce中可以简单设置page的属性让页面以pdf的方式显示内容, 当然了我们的page内容可以用Html的方式编写 设置方式为:renderAs="pdf" 请看如 ...
- 在Salesforce中向外公布Service去创建Lead,并且用Asp.Net去调用此Service
1):在Salesforce中如何配置,向外公布此Service,请看如下链接: http://www.shellblack.com/marketing/web-to-lead/ 2):如何在Asp. ...
- 在Salesforce中为Object创建Master-Detail(Child-Relationship)关联关系
在Salesforce中可以将两个Object建立起一对多的关联关系,本篇文章就简单的叙述一下将两个Object(EricSunObj & EricSunObjC)设置成Master-Deta ...
- 在Salesforce中创建Approval Process
在Salesforce中可以创建Approval Process来实现审批流程的功能,实际功能与我们常说的Workflow很相似,具体的设置步骤如下所示 1):选择对应的Object去创建对应的App ...
- 踩坑事件:windows操作系统下的eclipse中编写SparkSQL不能从本地读取或者保存parquet文件
这个大坑... .... 如题,在Windows的eclipse中编写SparkSQL代码时,编写如下代码时,一运行就抛出一堆空指针异常: // 首先还是创建SparkConf SparkConf c ...
- salesforce 零基础开发入门学习(十四)salesforce中工厂模式的运用
提到工厂模式,想必大家都很熟悉,工厂模式作为一种设计模式,同样在salesforce中适用. 举一个例子,笔作为基类,可以有钢笔,铅笔,圆珠笔等等.有一个笔的工厂,当你向它要钢笔,它就会生产一支钢笔; ...
- 在Salesforce中对某一个Object添加自定义的Button和Link
在Salesforce中可以对某一个Object添加自定义的Button和Link,来完成特定的逻辑过程,接下来以一个简单的实例来描述整个处理流程,实现的基本功能和我另外一篇文章中描述的功能是一致的( ...
- 在Salesforce中可以对某一个Object的Standard Button或Link进行重写
在Salesforce中可以对某一个Object的Standard Button或Link进行重写,来实现我们特定的逻辑过程,比如:在删除某个Object之前要判断该Object的某个Field的状态 ...
- 在Salesforce中调用外部系统所提供的的Web Service
这里需要提供外部service所对应的WSDL文件(Salesforce只支持从本地上传),并且提供的WSDL文件有如下两点要求: 1):wsdl 文件只能有一个binding,Salesforce是 ...
随机推荐
- WCF之安全性
WCF 客户端代理生成 通过SvcUtil.exe http://www.cnblogs.com/woxpp/p/6232298.html WCF 安全性 之 None http://www.cnbl ...
- android 6.0 高通平台sensor 工作机制及流程(原创)
最近工作上有碰到sensor的相关问题,正好分析下其流程作个笔记. 这个笔记分三个部分: sensor硬件和驱动的工作机制 sensor 上层app如何使用 从驱动到上层app这中间的流程是如何 Se ...
- ubuntu下安装gedit插件
因为gedit-plugins : 依赖: gir1.2-zeitgeist-2.0 所以首先 sudo apt-get install gir1.2-zeitgeist-2.0 如果报错可以先 su ...
- kendo-ui学习笔记(一)
1.top.jsp: <script src="<%=path%>/kendoui/js/jquery.min.js"></script> &l ...
- Http协议:彻底弄懂 Http 缓存机制 - 基于缓存策略三要素分解法
转载:http://mp.weixin.qq.com/s/uWPls0qrqJKHkHfNLmaenQ 导语 Http 缓存机制作为 web 性能优化的重要手段,对从事 Web 开发的小伙伴们来说是必 ...
- AIX下tar解包问题
今天,在AIX下安装tomcat,上传的版本是apache-tomcat-6.0.41.tar.gz,但用tar解压时出现以下问题: # tar xvf apache-tomcat-6.0.41.ta ...
- Python序列化之json与pickle
1.json介绍 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式. 易于人阅读和编写.同时也易于机器解析和生成. 它基于JavaScript Progra ...
- qt编译常见错误
一.fatal error: QWidget: 没有那个文件或目录 类似于找不到文件目录的,在.pro文件中添加 QT +=\ widgets 类似就可以编译通过
- OPENSSL编程入门学习
相关学习资料 http://bbs.pediy.com/showthread.php?t=92649 https://www.openssl.org https://www.google.com.hk ...
- channelartlist添加栏目链接
{dede:channelartlist} <a href='{dede:field name='typeurl'/}'></a> {/dede:channelartlist}