在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;
private String[] NV_type_info = new String[]{'NV','http://www.itvisions.com.au/ITVisions.WebServices/',null,'','-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;
private String[] FilterInfo_type_info = new String[]{'FilterInfo','http://www.itvisions.com.au/ITVisions.WebServices/',null,'','-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;
private String[] FeedName_type_info = new String[]{'FeedName','http://www.itvisions.com.au/ITVisions.WebServices/',null,'','','false'};
private String[] Filters_type_info = new String[]{'Filters','http://www.itvisions.com.au/ITVisions.WebServices/',null,'','','false'};
private String[] ChangedAfter_type_info = new String[]{'ChangedAfter','http://www.itvisions.com.au/ITVisions.WebServices/',null,'','','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;
private String[] ArrayOfNV_type_info = new String[]{'ArrayOfNV','http://www.itvisions.com.au/ITVisions.WebServices/',null,'','-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;
private String[] string_x_type_info = new String[]{'string','http://www.itvisions.com.au/ITVisions.WebServices/',null,'','-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;
private String[] FeedResult_type_info = new String[]{'FeedResult','http://www.itvisions.com.au/ITVisions.WebServices/',null,'','','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;
private String[] Name_type_info = new String[]{'Name','http://www.itvisions.com.au/ITVisions.WebServices/',null,'','','false'};
private String[] Values_type_info = new String[]{'Values','http://www.itvisions.com.au/ITVisions.WebServices/',null,'','','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 = [select id from User where id =: UserInfo.getUserId() limit ];
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 = [select id from User where id =: UserInfo.getUserId() limit ];
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];
if(accList != null && accList.size() > ){
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 = [select id from User where id =: UserInfo.getUserId() limit ];
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 = new CreditLimitController.CreditLimitInfo('', 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" 请看如 ...
- 如何在Ruby中编写微服务?
[编者按]本文作者为 Pierpaolo Frasa,文章通过详细的案例,介绍了在Ruby中编写微服务时所需注意的方方面面.系国内 ITOM 管理平台 OneAPM 编译呈现. 最近,大家都认为应当采 ...
- 大数据学习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 ...
- 在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,来完成特定的逻辑过程,接下来以一个简单的实例来描述整个处理流程,实现的基本功能和我另外一篇文章中描述的功能是一致的( ...
随机推荐
- Metronic 与 VS2013/2015 合作开发
Metronic 与 VS2013/2015 合作开发 去年购买了一个:METRONIC (http://www.keenthemes.com/) ,最近下了最新的版本:V3.7 ,解压缩后,目录 ...
- cat -n与nl的区别
cat -n filename:空行也算一行 nl filename:空行不算一行
- http apr 8080 exec 3解决
IDEA运行tomcat,总是出现这个错误. 解决: 在tomcat的配置里,加上下面这句话: -Xms256m -Xmx512m -XX:MaxNewSize=64m -XX:MaxPermSize ...
- zpf 路由功能
2015-4-11 20:51:06 又搞了一天, 解决了一堆bug, 重新规划了类文件夹, 改善自动加载功能 最新的特性就是支持子域名路由了 因为整个框架还在完善当中, 而且里边有好多接口有我自己申 ...
- ABAP 内表的行列转换-NEW
REPORT Z_TEST_COL_TO_ROW. TYPE-POOLS: slis. TABLES: mseg,mkpf. DATA: gd_fieldcat TYPE slis_t_fieldca ...
- 创建一个没有边框的并添加自定义文字的UISegmentedControl
//个性推荐 歌单 主播电台 排行榜 NSArray* promoteArray=@[@"个性推荐",@"歌单",@"主播电台",@&quo ...
- Effective C++ -----条款40:明智而审慎地使用多重继承
多重继承比单一继承复杂.它可能导致新的歧义性,以及对virtual继承的需要. virtual继承会增加大小.速度.初始化(及赋值)复杂度等等成本.如果virtual base classes不带任何 ...
- Effective C++ -----条款22:将成员变量声明为private
切记将成员变量声明为private.这可赋予客户访问数据的一致性.可细微划分访问控制.允诺约束条件获得保证,并提供class作者以充分的实现弹性. protected并不比public更具有封装性.
- 穹举,迭代,while循环。
所有循环 必要条件 : 初始条件(注意初始条件的位置) 循环条件 循环体 状态改变: 1.穷举 将所有可能性全部全部走一遍,使用IF筛选出满足的情况 使用循环语句 for ...
- 【leetcode】Reverse Linked List II (middle)
Reverse a linked list from position m to n. Do it in-place and in one-pass. For example:Given 1-> ...