Unit Test 也是一个 Class 文件,所以在创建 Unit Test 的时候要选择 Test Class 类型来创建,请看如下截图(在Eclipse中):

编写 Unit Test 基本流程为:

  1):创建模拟数据。

  2):调用Test.startTest方法。

  3):调用对应的我们所测试的方法。

  4):调用Test.stopTest()方法。

测试代码段一般会涉及到:测试属性,测试公共方法,测试静态方法,测试trigger。 请看如下代码段:

  1. @isTest(SeeAllData = true)
  2. private class EricSunUtilityTest {
  3.  
  4. static testMethod void myUnitTest() {
  5.  
  6. // first - what user profile are they? Sales Rep
  7. Profile p = [select id from Profile where Name = 'Sales Rep' limit 1];
  8. system.assert(p.id != null);
  9. User u = [select id, territory__c from User where ProfileId =:p.id and IsActive = true and territory__c != null limit 1];
  10. system.assert(u.id != null);
  11.  
  12. //**--------- create test data ---------------------**//
  13. // create test data
  14. Account a1 = new Account();
  15. a1.Name = 'Test Account001';
  16. a1.BDM_Owner__c = u.id;
  17. a1.Type = 'Prospect';
  18. insert a1;
  19. system.assert(a1.id != null);
  20.  
  21. EricSunObject__c object1 = new EricSunObject__c();
  22. object1.Name = 'Test Object001';
  23. object1.OwnerId = u.id;
  24. object1.MyDate = date.newinstance(2011,7,1);
  25.  
  26. system.runAs(u){
  27.  
  28. Test.startTest();
  29.  
  30. Test.setCurrentPage(Page.EricSunPage); //set which page
  31. EricSunController con = new EricSunController(); //init the
  32.  
  33. integer year = EricSunController.thisYear; //test public variable
  34.  
  35. //test special account owner
  36. ApexPages.currentPage().getParameters().put('uId',u.id); //set the parameter
  37. con.ChangeOwner(); //test public function
  38.  
  39. EricSunController.MyBillins_Target_All(u.id); //test static function (Visualforce.remoting.Manager.invokeAction --> Remote Action)
  40.  
  41. insert object1;
  42. system.assert(object1.id != null); //test trigger about EricSunObject__c (insert)
  43.  
  44. Test.stopTest();
  45. }
  46. }
  47. }

编写完测试代码后,如何进行测试代码运行呢?请看如下过程:

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

  1. //Generated by wsdl2apex
  2.  
  3. public class ITVDataFeedService {
  4. public class ArrayOfNV {
  5. public ITVDataFeedService.NV[] NV;
  6. private String[] NV_type_info = new String[]{'NV','http://www.itvisions.com.au/ITVisions.WebServices/',null,'','-1','true'};
  7. private String[] apex_schema_type_info = new String[]{'http://www.itvisions.com.au/ITVisions.WebServices/','true','false'};
  8. private String[] field_order_type_info = new String[]{'NV'};
  9. }
  10. public class ArrayOfFilterInfo {
  11. public ITVDataFeedService.FilterInfo[] FilterInfo;
  12. private String[] FilterInfo_type_info = new String[]{'FilterInfo','http://www.itvisions.com.au/ITVisions.WebServices/',null,'','-1','true'};
  13. private String[] apex_schema_type_info = new String[]{'http://www.itvisions.com.au/ITVisions.WebServices/','true','false'};
  14. private String[] field_order_type_info = new String[]{'FilterInfo'};
  15. }
  16. public class Feed_element {
  17. public String FeedName;
  18. public ITVDataFeedService.ArrayOfFilterInfo Filters;
  19. public DateTime ChangedAfter;
  20. private String[] FeedName_type_info = new String[]{'FeedName','http://www.itvisions.com.au/ITVisions.WebServices/',null,'','','false'};
  21. private String[] Filters_type_info = new String[]{'Filters','http://www.itvisions.com.au/ITVisions.WebServices/',null,'','','false'};
  22. private String[] ChangedAfter_type_info = new String[]{'ChangedAfter','http://www.itvisions.com.au/ITVisions.WebServices/',null,'','','true'};
  23. private String[] apex_schema_type_info = new String[]{'http://www.itvisions.com.au/ITVisions.WebServices/','true','false'};
  24. private String[] field_order_type_info = new String[]{'FeedName','Filters','ChangedAfter'};
  25. }
  26. public class NV {
  27. public String N;
  28. public String V;
  29. private String[] N_att_info = new String[]{'N'};
  30. private String[] V_att_info = new String[]{'V'};
  31. private String[] apex_schema_type_info = new String[]{'http://www.itvisions.com.au/ITVisions.WebServices/','true','false'};
  32. private String[] field_order_type_info = new String[]{};
  33. }
  34. public class ArrayOfArrayOfNV {
  35. public ITVDataFeedService.ArrayOfNV[] ArrayOfNV;
  36. private String[] ArrayOfNV_type_info = new String[]{'ArrayOfNV','http://www.itvisions.com.au/ITVisions.WebServices/',null,'','-1','true'};
  37. private String[] apex_schema_type_info = new String[]{'http://www.itvisions.com.au/ITVisions.WebServices/','true','false'};
  38. private String[] field_order_type_info = new String[]{'ArrayOfNV'};
  39. }
  40. public class ArrayOfString {
  41. public String[] string_x;
  42. private String[] string_x_type_info = new String[]{'string','http://www.itvisions.com.au/ITVisions.WebServices/',null,'','-1','true'};
  43. private String[] apex_schema_type_info = new String[]{'http://www.itvisions.com.au/ITVisions.WebServices/','true','false'};
  44. private String[] field_order_type_info = new String[]{'string_x'};
  45. }
  46. public class FeedResponse_element {
  47. public ITVDataFeedService.ArrayOfArrayOfNV FeedResult;
  48. private String[] FeedResult_type_info = new String[]{'FeedResult','http://www.itvisions.com.au/ITVisions.WebServices/',null,'','','false'};
  49. private String[] apex_schema_type_info = new String[]{'http://www.itvisions.com.au/ITVisions.WebServices/','true','false'};
  50. private String[] field_order_type_info = new String[]{'FeedResult'};
  51. }
  52. public class FilterInfo {
  53. public String Name;
  54. public ITVDataFeedService.ArrayOfString Values;
  55. private String[] Name_type_info = new String[]{'Name','http://www.itvisions.com.au/ITVisions.WebServices/',null,'','','false'};
  56. private String[] Values_type_info = new String[]{'Values','http://www.itvisions.com.au/ITVisions.WebServices/',null,'','','false'};
  57. private String[] apex_schema_type_info = new String[]{'http://www.itvisions.com.au/ITVisions.WebServices/','true','false'};
  58. private String[] field_order_type_info = new String[]{'Name','Values'};
  59. }
  60. public class DataFeedSoap {
  61. public String endpoint_x = 'https://corp-services.jbhifi.com.au/ITVisions.Webservices/DataFeed.asmx';
  62. public Map<String,String> inputHttpHeaders_x;
  63. public Map<String,String> outputHttpHeaders_x;
  64. public String clientCertName_x;
  65. public String clientCert_x;
  66. public String clientCertPasswd_x;
  67. public Integer timeout_x;
  68. private String[] ns_map_type_info = new String[]{'http://www.itvisions.com.au/ITVisions.WebServices/', 'ITVDataFeedService'};
  69. public ITVDataFeedService.ArrayOfArrayOfNV Feed(String FeedName,ITVDataFeedService.ArrayOfFilterInfo Filters,DateTime ChangedAfter) {
  70. ITVDataFeedService.Feed_element request_x = new ITVDataFeedService.Feed_element();
  71. request_x.FeedName = FeedName;
  72. request_x.Filters = Filters;
  73. request_x.ChangedAfter = ChangedAfter;
  74. ITVDataFeedService.FeedResponse_element response_x;
  75. Map<String, ITVDataFeedService.FeedResponse_element> response_map_x = new Map<String, ITVDataFeedService.FeedResponse_element>();
  76. response_map_x.put('response_x', response_x);
  77. WebServiceCallout.invoke(
  78. this,
  79. request_x,
  80. response_map_x,
  81. new String[]{endpoint_x,
  82. 'http://www.itvisions.com.au/ITVisions.WebServices/Feed',
  83. 'http://www.itvisions.com.au/ITVisions.WebServices/',
  84. 'Feed',
  85. 'http://www.itvisions.com.au/ITVisions.WebServices/',
  86. 'FeedResponse',
  87. 'ITVDataFeedService.FeedResponse_element'}
  88. );
  89. response_x = response_map_x.get('response_x');
  90. return response_x.FeedResult;
  91. }
  92. }
  93. }

2):Unit Test

  1. @isTest
  2. private with sharing class ITVDataFeedServiceTest {
  3.  
  4. static testMethod void coverTypes() {
  5. // query for a test user
  6. User u = [select id from User where id =: UserInfo.getUserId() limit ];
  7. system.assert(u.id != null);
  8.  
  9. // run test as current test user
  10. system.runAs(u){
  11.  
  12. // start test
  13. Test.startTest();
  14.  
  15. // cover inner class
  16. new ITVDataFeedService.ArrayOfNV();
  17. new ITVDataFeedService.ArrayOfFilterInfo();
  18. new ITVDataFeedService.Feed_element();
  19. new ITVDataFeedService.NV();
  20. new ITVDataFeedService.ArrayOfArrayOfNV();
  21. new ITVDataFeedService.ArrayOfString();
  22. new ITVDataFeedService.FeedResponse_element();
  23. new ITVDataFeedService.FilterInfo();
  24. new ITVDataFeedService.DataFeedSoap();
  25.  
  26. // end test
  27. Test.stopTest();
  28. }
  29. }
  30.  
  31. static testMethod void coverMethods()
  32. {
  33. // query for a test user
  34. User u = [select id from User where id =: UserInfo.getUserId() limit ];
  35. system.assert(u.id != null);
  36.  
  37. // run test as current test user
  38. system.runAs(u){
  39.  
  40. // start test
  41. Test.startTest();
  42.  
  43. // cover method
  44. new ITVDataFeedService.DataFeedSoap().Feed(null, null, null);
  45.  
  46. // end test
  47. Test.stopTest();
  48. }
  49. }
  50.  
  51. private class WebServiceMockImpl implements WebServiceMock
  52. {
  53. public void doInvoke(
  54. Object stub, Object request, Map<String, Object> response,
  55. String endpoint, String soapAction, String requestName,
  56. String responseNS, String responseName, String responseType)
  57. {
  58. if(request instanceof ITVDataFeedService.Feed_element)
  59. response.put('response_x', new ITVDataFeedService.FeedResponse_element());
  60. return;
  61. }
  62. }
  63.  
  64. }

如何对调用 Web Service 中某些方法的 Apex Class 进行 Unit Test 

1):调用Web Service的Apex Class

  1. public class CreditLimitController {
  2. //added an instance varaible for the standard controller
  3. private ApexPages.StandardController controller {get; set;}
  4. // the actual account
  5. private Account a;
  6.  
  7. public CreditLimitInfo creLimitInfo {get; set;}
  8.  
  9. private string feedName = 'CustomerCredit';
  10. private string filterInfoName = 'CustomerID';
  11. private ITVDataFeedService itvDFService = new ITVDataFeedService();
  12. private ITVDataFeedService.DataFeedSoap dfSoap = new ITVDataFeedService.DataFeedSoap();
  13.  
  14. private ITVDataFeedService.FilterInfo fInfo = new ITVDataFeedService.FilterInfo();
  15. private ITVDataFeedService.ArrayOfFilterInfo filterInfoArray = new ITVDataFeedService.ArrayOfFilterInfo();
  16. private ITVDataFeedService.ArrayOfString sArray = new ITVDataFeedService.ArrayOfString();
  17.  
  18. public CreditLimitController(ApexPages.StandardController controller) {
  19. //initialize the stanrdard controller
  20. this.controller = controller;
  21. this.a = (Account)controller.getRecord();
  22. this.creLimitInfo = getCreditLimitInfo(this.a);
  23. }
  24.  
  25. public CreditLimitInfo getCreditLimitInfo(Account acc) {
  26. // call web service to get the credit limit by account id
  27. fInfo.Name = filterInfoName;
  28.  
  29. string customerId = getCustomerId(acc);
  30. string[] sArr = new string[] { customerId };
  31. sArray.string_x = sArr;
  32.  
  33. fInfo.Values = sArray;
  34.  
  35. filterInfoArray.FilterInfo = new ITVDataFeedService.FilterInfo[] {fInfo};
  36.  
  37. ITVDataFeedService.ArrayOfArrayOfNV nvArrayArray = dfSoap.Feed(feedName, filterInfoArray, DateTime.now());
  38.  
  39. CreditLimitInfo currentCreditLimitInfo = new CreditLimitInfo();
  40. if(nvArrayArray != null && nvArrayArray.ArrayOfNV != null){
  41. for(ITVDataFeedService.ArrayOfNV aNv : nvArrayArray.ArrayOfNV){
  42. for(ITVDataFeedService.NV nv : aNv.NV){
  43. if(nv.N == 'CustomerID'){
  44. currentCreditLimitInfo.CustomerId = nv.V;
  45. }
  46. else if(nv.N == 'CreditLimit'){
  47. currentCreditLimitInfo.CreditLimit = Decimal.valueOf(nv.V);
  48. }
  49. else if(nv.N == 'AvailableCredit'){
  50. currentCreditLimitInfo.AvailableCredit = Decimal.valueOf(nv.V);
  51. }
  52. else if(nv.N == 'Balance'){
  53. currentCreditLimitInfo.Balance = Decimal.valueOf(nv.V);
  54. }
  55. }
  56. }
  57. }
  58. return currentCreditLimitInfo;
  59. }
  60.  
  61. private string getCustomerId(Account acc){
  62. string customerId = '';
  63. if(acc != null && acc.Id != null){
  64. List<Account> accList = [Select AccountNumber From Account Where Id =: acc.Id];
  65. if(accList != null && accList.size() > ){
  66. customerId = accList[].AccountNumber;
  67. }
  68. }
  69. return customerId;
  70. }
  71.  
  72. public class CreditLimitInfo {
  73. public string CustomerId {get;set;}
  74. public decimal CreditLimit {get;set;}
  75. public decimal AvailableCredit {get;set;}
  76. public decimal Balance {get;set;}
  77.  
  78. public CreditLimitInfo(){
  79. CustomerId = '';
  80. CreditLimit = ;
  81. AvailableCredit = ;
  82. Balance = ;
  83. }
  84.  
  85. public CreditLimitInfo(string cusId, decimal creLimit, decimal avaCredit, decimal bal){
  86. CustomerId = cusId;
  87. CreditLimit = creLimit;
  88. AvailableCredit = avaCredit;
  89. Balance = bal;
  90. }
  91. }
  92. }

2):Unit Test

  1. @isTest
  2. private class CreditLimitControllerTest {
  3.  
  4. static testMethod void myUnitTest() {
  5. // query for a test user
  6. User u = [select id from User where id =: UserInfo.getUserId() limit ];
  7. system.assert(u.id != null);
  8.  
  9. // insert test data
  10. Account account001 = new Account(
  11. Name = 'Test Account 0101',
  12. AccountNumber = 'IN1200047',
  13. Credit_Type__c = 'Account'
  14. );
  15. insert account001;
  16. system.assert(account001.id != null);
  17.  
  18. // run test as current test user
  19. system.runAs(u){
  20.  
  21. // start test
  22. Test.startTest();
  23.  
  24. // This causes a fake response to be generated
  25. Test.setMock(WebServiceMock.class, new WebServiceMockImpl());
  26.  
  27. Test.setCurrentPage(Page.CreditLimit);
  28. ApexPages.StandardController sc = new ApexPages.StandardController(account001);
  29.  
  30. CreditLimitController con = new CreditLimitController(sc);
  31.  
  32. // test the constructor contains multiple parameters
  33. CreditLimitController.CreditLimitInfo testCLI = new CreditLimitController.CreditLimitInfo('', 1111.00, 1111.00, 1111.00);
  34.  
  35. // end test
  36. Test.stopTest();
  37. }
  38. }
  39.  
  40. private class WebServiceMockImpl implements WebServiceMock
  41. {
  42. public void doInvoke(
  43. Object stub, Object request, Map<String, Object> response,
  44. String endpoint, String soapAction, String requestName,
  45. String responseNS, String responseName, String responseType)
  46. {
  47. if(request instanceof ITVDataFeedService.Feed_element){
  48. // generate the fake data to test
  49. ITVDataFeedService.FeedResponse_element feedRes = new ITVDataFeedService.FeedResponse_element();
  50. ITVDataFeedService.ArrayOfArrayOfNV aaOfNV = new ITVDataFeedService.ArrayOfArrayOfNV();
  51.  
  52. ITVDataFeedService.ArrayOfNV aOfNV = new ITVDataFeedService.ArrayOfNV();
  53.  
  54. ITVDataFeedService.NV nvCustomerID = new ITVDataFeedService.NV();
  55. nvCustomerID.N = 'CustomerID';
  56. nvCustomerID.V = 'IN1200047';
  57.  
  58. ITVDataFeedService.NV nvCreditLimit = new ITVDataFeedService.NV();
  59. nvCreditLimit.N = 'CreditLimit';
  60. nvCreditLimit.V = '1000.11';
  61.  
  62. ITVDataFeedService.NV nvAvailableCredit = new ITVDataFeedService.NV();
  63. nvAvailableCredit.N = 'AvailableCredit';
  64. nvAvailableCredit.V = '1000.11';
  65.  
  66. ITVDataFeedService.NV nvBalance = new ITVDataFeedService.NV();
  67. nvBalance.N = 'Balance';
  68. nvBalance.V = '1000.11';
  69.  
  70. ITVDataFeedService.NV[] nvArray = new ITVDataFeedService.NV[] { nvCustomerID, nvCreditLimit, nvAvailableCredit, nvBalance };
  71.  
  72. aOfNV.NV = nvArray;
  73.  
  74. ITVDataFeedService.ArrayOfNV[] aOfNVArray = new ITVDataFeedService.ArrayOfNV[] { aOfNV };
  75.  
  76. aaOfNV.ArrayOfNV = aOfNVArray;
  77.  
  78. feedRes.FeedResult = aaOfNV;
  79.  
  80. // set the fake data to response
  81. response.put('response_x', feedRes);
  82. }
  83. }
  84. }
  85. }

更多详细信息请看如下链接:

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的更多相关文章

  1. 在Salesforce中以PDF的格式显示对应的页面

    在Salesforce中可以简单设置page的属性让页面以pdf的方式显示内容, 当然了我们的page内容可以用Html的方式编写 设置方式为:renderAs="pdf" 请看如 ...

  2. 如何在Ruby中编写微服务?

    [编者按]本文作者为 Pierpaolo Frasa,文章通过详细的案例,介绍了在Ruby中编写微服务时所需注意的方方面面.系国内 ITOM 管理平台 OneAPM 编译呈现. 最近,大家都认为应当采 ...

  3. 大数据学习day25------spark08-----1. 读取数据库的形式创建DataFrame 2. Parquet格式的数据源 3. Orc格式的数据源 4.spark_sql整合hive 5.在IDEA中编写spark程序(用来操作hive) 6. SQL风格和DSL风格以及RDD的形式计算连续登陆三天的用户

    1. 读取数据库的形式创建DataFrame DataFrameFromJDBC object DataFrameFromJDBC { def main(args: Array[String]): U ...

  4. 在Salesforce中向外公布Service去创建Lead,并且用Asp.Net去调用此Service

    1):在Salesforce中如何配置,向外公布此Service,请看如下链接: http://www.shellblack.com/marketing/web-to-lead/ 2):如何在Asp. ...

  5. 在Salesforce中为Object创建Master-Detail(Child-Relationship)关联关系

    在Salesforce中可以将两个Object建立起一对多的关联关系,本篇文章就简单的叙述一下将两个Object(EricSunObj & EricSunObjC)设置成Master-Deta ...

  6. 在Salesforce中创建Approval Process

    在Salesforce中可以创建Approval Process来实现审批流程的功能,实际功能与我们常说的Workflow很相似,具体的设置步骤如下所示 1):选择对应的Object去创建对应的App ...

  7. 踩坑事件:windows操作系统下的eclipse中编写SparkSQL不能从本地读取或者保存parquet文件

    这个大坑... .... 如题,在Windows的eclipse中编写SparkSQL代码时,编写如下代码时,一运行就抛出一堆空指针异常: // 首先还是创建SparkConf SparkConf c ...

  8. salesforce 零基础开发入门学习(十四)salesforce中工厂模式的运用

    提到工厂模式,想必大家都很熟悉,工厂模式作为一种设计模式,同样在salesforce中适用. 举一个例子,笔作为基类,可以有钢笔,铅笔,圆珠笔等等.有一个笔的工厂,当你向它要钢笔,它就会生产一支钢笔; ...

  9. 在Salesforce中对某一个Object添加自定义的Button和Link

    在Salesforce中可以对某一个Object添加自定义的Button和Link,来完成特定的逻辑过程,接下来以一个简单的实例来描述整个处理流程,实现的基本功能和我另外一篇文章中描述的功能是一致的( ...

随机推荐

  1. mysql查询当前正在使用数据库

    1.select database(): 2.status: 3.show tables:

  2. Silverlight 动画性能

    通过几个配置可以提高动画性能: Desired Frame Rate 在WEB项目中配置: <div id="silverlightControlHost"> < ...

  3. 【hihoCoder】第20周 线段树

    题目: 输入 每个测试点(输入文件)有且仅有一组测试数据. 每组测试数据的第1行为一个整数N,意义如前文所述. 每组测试数据的第2行为N个整数,分别描述每种商品的重量,其中第i个整数表示标号为i的商品 ...

  4. 【mysql】Blob类型

    来源:http://qgyang.blog.sohu.com/115847378.html 一般在需要存储较大数据时使用Bolb MySql的Bolb四种类型 MySQL中,BLOB是一个二进制大型对 ...

  5. NEFU 505 超级红与黑 (高斯消元)

    题目链接 中文题,改下模板构造一下就能过了,数据有点水,不过还是需要自由变元枚举的. #include <iostream> #include <cstdio> #includ ...

  6. MyEclipse/Eclipse中修改包的显示结构

    操作如下:

  7. centOS填坑笔记(一)

    第一次使用centOS安装软件时,对二进制包的./configure进行配置时(./configure是源代码安装的第一步,主要的作用是对即将安装的软件进行配置,)报错:WARNING: failed ...

  8. js对象的创建与原型总结

    //1 新建对象 var box = new Object(); box.name = "lee"; box.age = 100; box.run = function(){ re ...

  9. 关于ActionContext.getContext()的用法心得

    转: 为了避免与Servlet API耦合在一起,方便Action类做单元测试,Struts 2对HttpServletRequest.HttpSession和ServletContext进行了封装, ...

  10. Linux安装mysql最新版本纪要

    http://blog.csdn.net/frt007/article/details/50184143 http://blog.csdn.net/wb96a1007/article/details/ ...