今天這篇是延續(xù)Salesforce開發(fā)教程(一)诅岩、Salesforce開發(fā)教程(二)的內(nèi)容,對之前沒涉及到的主題進(jìn)行的補充带膜。主要包括Unit Test吩谦、Batch、Schedule Job膝藕、Rest和Soap相關(guān)內(nèi)容式廷。
測試類
當(dāng)我們寫完某個功能的時候,怎么能夠保證自己寫的代碼正常運行起來呢芭挽?大家可能會說測試一下就可以了滑废,那是不是這樣子呢?其實測試分為單元測試袜爪、集成測試蠕趁、功能測試,從前到后分別對應(yīng)著三個階段辛馆,這里的測試類指的是單元測試俺陋,為了能夠讓集成測試和功能測試順利的運行起來,作為開發(fā)者昙篙,應(yīng)該能夠保證單元測試正常運行倔韭,保證函數(shù)方法是沒問題的,后面的集成瓢对、功能測試才能正常順利進(jìn)行;換句話說胰苏,之所有單元測試這么重要硕蛹,是為了能夠?qū)⒋a問題提前暴露出來醇疼,盡早的解決。所以我們應(yīng)該除了將功能開發(fā)完成后法焰,還需要通過測試類來驗證功能是否完整秧荆;除此以外Salesforce會要求代碼的單元測試覆蓋率達(dá)到75%以上,所以單元測試的重要性就不言而喻了埃仪。下面我們來看看在Salesforce中怎樣進(jìn)行單元測試乙濒?
單元測試的語法很簡單:
@isTest
static void testName() {
// code
}
這是一個單元測試方法,需要將這個方法放到下面的Class中:
@isTest
private class MyTestClass {
@isTest
static void testName() {
// code
}
}
簡單可以簡測試類的過程分為三個步驟:
- 準(zhǔn)備數(shù)據(jù)
這里的數(shù)據(jù)指的是運行測試類數(shù)據(jù)卵蛉,每當(dāng)測試類運行完成后颁股,數(shù)據(jù)庫的數(shù)據(jù)會被回滾,不必?fù)?dān)心測試類中修改的數(shù)據(jù)影響到數(shù)據(jù)庫傻丝。這里注意提倡測試類用到的數(shù)據(jù)應(yīng)該避免依賴于某個組織(不建議使用SeeAllData=true標(biāo)注)甘有;推薦你使用@testSetup申明setup方法準(zhǔn)備數(shù)據(jù);另外需要注意的是葡缰,Salesforce有一些系統(tǒng)限制是難以避免的(比如Soql 101 錯誤)亏掀,出現(xiàn)這樣的錯誤后,需要優(yōu)化一下Soql和DML操作泛释。 - 調(diào)用要測試的類
實例化需要測試的Class滤愕,調(diào)用相應(yīng)的方法就可以了;注意的是除了正向測試怜校,還應(yīng)該進(jìn)行反向功能測試间影,從而提高代碼的健壯性。 - 斷言方法輸出的內(nèi)容是否和預(yù)期的一致
每次運行測試類方法都應(yīng)該進(jìn)行assert韭畸,從而保證要驗證的方法是沒有問題的宇智;建議每個測試方法至少包含一個assert語句。
今天給大家準(zhǔn)備了一個寫Unit Test的模板胰丁,可以參考使用:
@isTest
private class MyTestClass {//Class申明為Private且名字應(yīng)該能夠識別出測試的類
@testSetup
static void setUp(){
//code 準(zhǔn)備數(shù)據(jù)随橘,DML操作應(yīng)該在這個方法里面完成
}
@isTest
static void myMethodTest() {//Method名稱應(yīng)該能夠識別出測試的功能
Test.startTest();
System.assert(xxx);
Test.stopTest();
System.assert(xxx);//每個測試方法照燒包含一個assert語句
}
}
如果你對UT還想有更多的思考和實踐,希望我之前寫過的一篇Mock Framework For Unit Test可以幫助到你锦庸。
Batch和Schedule Job
針對Batch相信大家不會陌生机蔗,一句話概括呢,就是用來處理數(shù)據(jù)量大的場景甘萧;為什么我們要用Batch萝嘁,而不使用普通的類呢,總結(jié)了一下扬卷,Batch大概有下面三個優(yōu)點:
- 可以提高Salesforce的系統(tǒng)限制牙言,普通Class的Soql的每個事務(wù)查詢次數(shù)是100次,而用Batch可以達(dá)到200次怪得;其次是數(shù)據(jù)量的大小咱枉,普通Class的Soql查詢數(shù)據(jù)上限是50 000卑硫,Batch可以達(dá)到50 000 000。
- Batch可以批量處理數(shù)據(jù)蚕断,在每次執(zhí)行execute的方法時候欢伏,可以接收任意條數(shù)大小的數(shù)據(jù)量,每個Batch最多可以處理200條數(shù)據(jù)亿乳,意味著你可以將數(shù)據(jù)量分為200一個批次執(zhí)行硝拧。
- Batch可以和定時任務(wù)結(jié)合在一塊,做一些日常工作葛假,比如系統(tǒng)定期生成任務(wù)或者清理數(shù)據(jù)障陶。
下面我們來看一下怎么寫一個Batch,實現(xiàn)Database.Batchable接口就可以了:
這個接口有三個方法需要實現(xiàn):
- 準(zhǔn)備數(shù)據(jù)
global (Database.QueryLocator | Iterable<sObject>) start(Database.BatchableContext bc) {}
這個方法可以返回QueryLocator或者Iterable對象桐款,注意如果用Iterable的話咸这,Soql查詢上限是50 000。 - 執(zhí)行邏輯
global void execute(Database.BatchableContext BC, list< sObject> scope){}
每個Batch執(zhí)行的時候都會調(diào)用這個方法魔眨。 - Finish方法
global void finish(Database.BatchableContext BC){}
當(dāng)所有的Batch執(zhí)行完后會調(diào)用媳维,可能會進(jìn)行其他的操作,比如生成日志或者發(fā)送郵件等操作遏暴。
一個簡單Batch的實現(xiàn):
global class MyFirstBatch implements Database.Batchable<sObject> {
public String query;
global AddPunishmentInformationOpp(String query) {
this.query =query;
}
global Database.QueryLocator start(Database.BatchableContext bc) {
return Database.getQueryLocator(query);
}
global void execute(Database.BatchableContext BC, list<Sobject> scope) {
//執(zhí)行語句
}
global void finish(Database.BatchableContext BC) {
//發(fā)送郵件
}
}
當(dāng)一個Bacth執(zhí)行的時候如果需要用到多個Sobject對象怎么處理呢侄刽?這時候可以嘗試使用** Iterable**定義數(shù)據(jù)范圍,具體實現(xiàn)步驟有三個:
- 定義迭代器
global class CustomIterable implements Iterator<SObject>{
List<SObject> sobjectList {get; set;}
Integer i {get; set;}
public CustomCalculateIterable(){
sobjectList = new List<SObject>();
List<Account> accList = new List<Account>([select id,name from Account]);
List<Opportunity> oppList = new List<Opportunity>([select id,name from Opportunity]);
sobjectList.add(accList);
sobjectList.add(oppList);
i = 0;
}
global boolean hasNext(){
if(i >= sobjectList.size())
return false;
else
return true;
}
global SObject next(){
// 8 is an arbitrary
// constant in this example
// that represents the
// maximum size of the list.
if(i == 8){ i++; return null;}
i=i+1;
return sobjectList[i-1];
}
}
- 定義一個Class返回可迭代對象
global class CustomSobjectIterable implements iterable<SObject>{
global Iterator<SObject> Iterator(){
return new CustomIterable();
}
}
- 定義Batch實現(xiàn)類朋凉,調(diào)用上面的CustomSobjectIterable類
global class MyFirstBatch implements Database.Batchable<SObject>{
global Iterable<Sobject> start(Database.batchableContext info){
return new CustomSobjectIterable();
}
global void execute(Database.BatchableContext bc,List<SObject> scope){
for(SObject so : scope){
String objectType = String.valueof(so.getSObjectType());
if(objectType == 'Opportunity'){
//code
}
if(objectType = 'Account'){
//code
}
}
}
global void finish(Database.BatchableContext bc){
}
}
到現(xiàn)在為止州丹,我們可以通過實現(xiàn)Batch做了一些事情,那么怎么執(zhí)行Batch呢杂彭?首先明白的是Batch是異步執(zhí)行的墓毒,那么Bacth執(zhí)行完后,可能不會很快的看到結(jié)果亲怠,不過你可以通過Apex Jobs來查看執(zhí)行狀態(tài)所计;Batch執(zhí)行可以在控制臺調(diào)用下面的語句:
MyFirstBatch b = new MyFirstBatch();
database.executeBatch(b);
正如你所看到的,我們可以通過上述語句來調(diào)用Batch团秽,那么我們同樣的可以在Trigger主胧、普通的類方法中來調(diào)用Batch;下面我想著重說一下在定時任務(wù)中調(diào)用Batch习勤,實際項目中常常會有定時發(fā)郵件踪栋、生成日志、清理數(shù)據(jù)的工作图毕,那么這些任務(wù)常常伴隨的數(shù)據(jù)量是比較大的夷都,在Salesforce中只能通過Batch來操作,那怎樣定時來執(zhí)行這個操作呢予颤?有三個步驟:
- 定義Scheduler
想要一個任務(wù)定時執(zhí)行囤官,必須得先實現(xiàn)一個Scheduler類厢破,這個類需要實現(xiàn)Schedulable接口,如下所示:
global class MyFirstScheduler implements Schedulable {
global void execute(SchedulableContext sc) {
//code
}
}
- Scheduler中調(diào)用Batch
global class MyFirstScheduler implements Schedulable {
global void execute(SchedulableContext sc) {
Database.executeBatch(new MyFirstBatch);
}
}
- 定義Scheduler執(zhí)行頻率
Scheduler的執(zhí)行可以通過配置來實現(xiàn)治拿,也可以通過system.schedule方法來實現(xiàn)。
到現(xiàn)在為止笆焰,我們已經(jīng)知道實現(xiàn)Bacth和Scheduler劫谅,并且也在Scheduler中調(diào)用了Batch,這種方式在實際項目中用到的也比較多嚷掠,希望你能會有所收獲捏检。
REST和SOAP
為了能夠與其他系統(tǒng)進(jìn)行集成,Salesforce提供了Rest和Soap兩種API不皆。那么什么是REST?什么是SOAP呢贯城?
- REST: The Representational State Transfer,這是輕量級的系統(tǒng)集成模式霹娄,所有服務(wù)抽象為可訪問資源能犯,調(diào)用者通過URL就可以和系統(tǒng)發(fā)生交互(增、刪犬耻、改踩晶、查)。
- SOAP: The Simple Object Access Protocol, 看字面意思是數(shù)據(jù)交互協(xié)議枕磁,用XML定義數(shù)據(jù)格式渡蜻;在使用Web Service的過程中,需要獲取到服務(wù)資源的WSDL(Web Service Description Language)文件计济,然后通過POST請求獲取服務(wù)器應(yīng)答茸苇。
這兩種方式的比較可以參考WebService的兩種方式Soap和Rest比較。如果你想對Salesforce的API想有更多的了解沦寂,推薦大家做一下Lightning Platform API Basics模塊学密;當(dāng)你開發(fā)完接口之后,需要用第三方工具進(jìn)行測試凑队,之前我寫過一篇用使用Postman對Salesforce進(jìn)行接口測試则果,如果要測試SOAP的話,可以使用SOAP UI進(jìn)行驗證漩氨,參考Salesforce中SOAP的實踐西壮。
至此,Salesforce開發(fā)教程系列終于完成了叫惊,從第一篇對Salesforce的入門了解款青,第二篇的開發(fā)實踐,今天這篇內(nèi)容算是對第二篇的補充霍狰;希望通過這個開發(fā)教程系列可以幫助到你抡草,文章中如有問題請盡情指出饰及。再次感謝你的閱讀,感謝支持康震!