单元测试类

Salesforce中为Apex语言提供了完整的单元测试流程,包括单元测试类、测试的运行和结果分析等。

单元测试类是一种特殊的Apex类,基本语法和普通的Apex类一样。

单元测试类的结构是:

@isTest
private class MyTestClass {
@isTest
static void myTest() {
// Test
}
}

可以看到,“@isTest”是一个关键的注解,带有它的类和方法会被系统认定为单元测试的类和方法。

对于单元测试的方法,可以用“testMethod”关键字代替“@isTest”注解,比如:

static testMethod void myTest() {
// Test
}

单元测试的方法必须定义在单元测试类中。

单元测试类和方法的访问控制权限并不重要。无论是定义为public还是private,系统都可以进入其中并执行测试代码。

断言函数

系统中提供了一组断言函数来进行结果的比较。它们主要包括:

  • System.assert(condition, msg):用于判断某条件是否为真,如果不为真则给出错误信息
  • System.assertEquals(expected, actual, msg):用于判断期望的值是否和实际的值相同,如果不同则给出错误信息
  • System.assertNotEquals(expected, actual, msg):用于判断期望的值是否和实际的值不同,如果相同则给出错误信息

单元测试示例

在Developer Console中,可以新建两个Apex类,一个作为正常的类,另一个作为单元测试类使用。

正常的类中写入如下代码,将美元转化为欧元,汇率取0.9:

public class CurrencyConverter {
public static Decimal GetEuroFromDollar(Decimal dollar) {
Decimal euro = dollar * 0.9;
return euro;
}
}

在单元测试类中写入如下代码,测试函数的执行情况:

@isTest
private class CurrencyConverterTest {
@isTest
static void testGetEuroFromDollar() {
Decimal euro = CurrencyConverter.GetEuroFromDollar(100);
System.assertEquals(90, euro);
}
}

在Developer Console中,可以直接点击单元测试类窗口右上角的“Run Test”按钮,则类中的测试方法会被自动执行,在窗口下方的控制台中会显示结果。“Logs”标签中会显示执行测试的日志,“Tests”标签中会显示哪些测试函数被执行以及执行结果。

代码覆盖率

Salesforce非常注重代码的覆盖率。系统规定的最低代码覆盖率是75%,也就是说每一个类的单元测试的范围要包括被测试的类的至少75%的代码。

在Developer Console中,当执行完一个单元测试类的所有测试之后,打开被测试的类,在编辑区域的左上方会有“Code Coverage”按钮,点击即可看到代码覆盖率。在下方“Tests”部分的右侧是所有类的覆盖率一览。

单元测试中的数据

在单元测试中,有时候需要新建对象数据或修改对象数据。所有单元测试中的数据都是独立于实际数据库的。

在单元测试开始的时候,默认为数据库是空的,不能直接从中读取已经存在的数据,必须手动新建。

当单元测试结束时,所有往数据库中增加、修改的数据都会被清理掉。

注意:虽然单元测试的数据独立于实际数据库,但是在单元测试中的数据也会暂时被保存在数据库中。所以如果在单元测试中新建了某条记录,而此记录的某些字段违反了验证规则,或者某些数据必须唯一的字段和显存的某些记录相同,系统会报错,测试无法继续进行。

比如:系统中设置了验证规则:所有“Account”对象的名字值是唯一的,并且已经存在了一个叫“Test Account”的对象,那么在测试类中新建一个叫“Test Account”的对象,则系统会报错。

设置测试数据

如果一个单元测试类中包含若干测试函数,而这些函数会用相同的一组数据,则可以使用“testSetup”注解定义单元测试类的初始化函数。

在初始化函数中建立的测试数据可以供每一个单元测试函数使用,并且在测试函数中对于数据库的更改并不会带到其他测试函数中,所以每一个测试函数在运行时,数据库中的状态都和执行完初始化函数的状态一样。

示例代码:

@isTest
private class ExampleTestSetup { // 使用testSetup定义初始化函数
@testSetup
static void setup() {
List<Account> testAccts = new List<Account>();
for(Integer i=0;i<2;i++) {
testAccts.add(new Account(Name = 'TestAcct'+i));
}
insert testAccts;
} @isTest
static void testMethod1() {
// 在setup()函数中插入数据库的testAccts对象可以在这里直接使用,并且其他测试函数对数据的更改不会在此函数中产生作用 Account acct = [SELECT Id FROM Account WHERE Name='TestAcct0' LIMIT 1];
acct.Phone = '555-1212';
update acct; // ...
} @isTest
static void testMethod2() {
// 在setup()函数中插入数据库的testAccts对象可以在这里直接使用,并且其他测试函数对数据的更改不会在此函数中产生作用
// ...
} }

单元测试的限制

单元测试类中,有若干限制:

  • 系统无法发送邮件
  • 系统无法和外部的网络服务通讯,所以无法通过调用web service得到数据,但是可以自己建立模拟数据
  • 无法使用SOSL查询,但是可以使用Test.setFixedSearchResults()方法来自己建立模拟的查询结果

Apex单元测试的更多相关文章

  1. Apex 单元测试辅助函数简介

    startTest和stopTest的使用 在Apex的Test类中,有startTest和stopTest两个函数.这两个函数经常配对使用. 每个单元测试函数都只能调用它们一次. startTest ...

  2. Apex 中文件夹相关的单元测试

    Salesforce 中的文件夹 在 Salesforce 中,我们可以建立各种文档.报表.仪表板.电子邮件模板等.它们都被保存在相应的文件夹中. Salesforce 的后端将这些文件夹保存为 Fo ...

  3. 异步 Apex 类

    异步Apex类 一个Apex类可以定义为异步类,用于异步执行. 异步类可以通过多种方式实现: Future注解 批处理 Queueable接口 Schedulable接口 Future注解 使用Fut ...

  4. 用 FFLIB 实现 Apex 企业设计模式

    Apex 企业设计模式将应用分为服务层.模型层.选择逻辑层.工作单元几个部分.FFLIB 是一个开源的 Apex 框架,可以帮助开发者快速建立相关的功能. FFLIB 的安装 FFLIB 可以直接部署 ...

  5. 从网络服务生成Apex类

    使用WSDL2Apex从网络服务生成Apex类 如果某个网络服务被定义在WSDL文件中,而Salesforce必须使用SOAP和网络服务进行通信,则这种情况在某些时候会为开发者带来很多麻烦.为了简化S ...

  6. Apex API 请求

    Salesforce与网络服务的通信 在Salesforce中可以利用Apex类与远程站点的网络服务进行通信.当远程网络服务支持REST方法时,开发者可以利用Apex代码进行数据的操作. 设置远程站点 ...

  7. Intellij idea添加单元测试工具

    1.idea 版本是14.0.0 ,默认带有Junit,但是不能自动生成单元测试,需要下载JunitGererator2.0插件 2.Settings -Plugins,下载 JunitGenerat ...

  8. Python的单元测试(二)

    title: Python的单元测试(二) date: 2015-03-04 19:08:20 categories: Python tags: [Python,单元测试] --- 在Python的单 ...

  9. Python的单元测试(一)

    title: Python的单元测试(一) author: 青南 date: 2015-02-27 22:50:47 categories: Python tags: [Python,单元测试] -- ...

随机推荐

  1. JDBC的使用和SQL注入问题

    基本的JDBC使用: package demo; import java.sql.Connection; import java.sql.DriverManager; import java.sql. ...

  2. Java学习笔记31(集合框架五:set接口、哈希表的介绍)

    set接口的特点: 1.不包含重复元素 2.set集合没有索引,只能用迭代器或增强for循环遍历 3.set的底层是map集合 方法和Collection的方法基本一样 set接口的实现类HashSe ...

  3. 第二篇:服务消费者(RestTemplate+ribbon)

    第一篇讲了服务的注册,这篇来说说服务的调用,服务与服务的通讯是基于http restful,springcloud的服务调用是通过ribbon方式的,客户端的负载均衡. Talk is cheap.S ...

  4. 【2019北京集训测试赛(七)】 操作 分治+FFT+生成函数

    题目大意:你有$n$个操作和一个初始为$0$的变量$x$. 第$i$个操作为:以$P_i$的概率给$x$加上$A_i$,剩下$1-P_i$的概率给$x$乘上$B_i$. 你袭击生成了一个长度为$n$的 ...

  5. Xcode 8.X Command Line Tools

    Summary Step 1. Upgrade Your System to macOS Sierra Step 2. Open the Terminal Application Step 3. Is ...

  6. Facelets应用程序的生命周期

    当客户端(如浏览器)向使用Facelets创建的页面发出新的请求时,会创建一个新的组件树或 javax.faces.component.UIViewRoot将其创建并放入FacesContext. 该 ...

  7. 如何设计和实现高可用的MySQL

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由腾讯云数据库 TencentDB发表于云+社区专栏 王甲坤,腾讯高级工程师.腾讯云关系型数据库MySQL负责人,拥有多年客户端.数据库 ...

  8. [TensorFlow] Introduction to TensorFlow Datasets and Estimators

    Datasets and Estimators are two key TensorFlow features you should use: Datasets: The best practice ...

  9. XSS漏洞扫描工具:BruteXSS

    下载Brute,一个xss漏洞扫描工具:https://codeload.github.com/shawarkhanethicalhacker/BruteXSS/legacy.zip/master 我 ...

  10. BizTalk 2010/2013 EDI B2B项目实践(1)

    BizTalk 2010/2013 EDI B2B项目实践(1) BizTalk开发标准EDI B2B是件非常容易的事情,但对于初学者可能有很多专业术语不太理解,不知道如何下手,我之前开始学的时候虽然 ...