unittest.mock 包

主要接口

构造对象

func mock

public func mock<T>(): T

创建类型 T 的 mock object, 这个对象默认情况下,所有的成员函数、属性或运算符重载函数没有任何具体实现。 可以通过 @On 指定这个对象的成员函数、属性或运算符重载函数的行为。

返回值:类型 T 的 mock object

enum StubMode

public enum StubMode {
    | ReturnsDefaults
    | SyntheticFields
} 

功能:为 mock object 指定额外的默认行为,显示的桩行为优先级高于此默认行为。

ReturnsDefaults
ReturnsDefaults

mock object 的返回支持类型的成员,指定其默认返回空或者 false 等值。

SyntheticFields
SyntheticFields

mock object 将会简化合成字段的赋值流程。

func mock

public func mock<T>(modes: Array<StubMode>): T

创建类型 T 的 mock object 并指定其桩模式。 可以通过 @On 指定这个对象的成员函数、属性或运算符重载函数的行为。未通过 @On 指定的函数将应用对应桩模式下的行为。

参数:

  • modes: mock 对象的桩模式

返回值:类型 T 的 mock object

func spy

public func spy<T>(objectToSpyOn: T): T

创建类型 T 的 spy object ( mock object 的扩展,对象的成员拥有默认实现的“骨架”对象)。 这个对象包装了所传入的对象,并且默认情况下成员函数、属性或运算符重载函数实现为对这个传入的实例对象的对应成员函数、属性或运算符重载函数的调用。 可以通过 @On 重载这个对象的成员函数、属性或运算符重载函数的行为。

返回值:类型 T 的 spy object

行为定义

interface ActionSelector

public interface ActionSelector<R> {
    func returns(value: R): CardinalitySelector<R>
    func returns(valueFactory: () -> R): CardinalitySelector<R>
    func returnsConsecutively(values: Array<R>): Continuation<R>
    func returnsConsecutively(values: ArrayList<R>): Continuation<R>
    func throws(exception: Exception): CardinalitySelector<R>
    func throws(exceptionFactory: () -> Exception): CardinalitySelector<R>
    func fails(): Unit
    func callsOriginal(): CardinalitySelector<R>
}

此接口提供了为成员函数指定一个行为的 API ,并允许链式调用。 入参为 mock objectspy object 的某个成员函数的调用表达式的 @On 宏调用表达式,将返回 ActionSelector<R> 的实例(其中 R 代表正在配置的函数成员的返回值类型)。 即,此接口中的 API 可为成员函数插入桩代码。 另,为方便起见,后文将 @On 表达式的入参中的成员函数调用表达式称为“桩表达式”。

func returns
func returns(value: R): CardinalitySelector<R>

功能:定义“桩表达式”返回指定值的行为。

参数:

  • values: 预期“桩表达式”的返回值

返回值:定义了“桩表达式”返回行为的 CardinalitySelector 对象实例

func returns
func returns(valueFactory: () -> R): CardinalitySelector<R>

功能:定义“桩表达式”返回指定的值的行为,该值由传入的闭包生成。

参数:

  • values: 生成预期返回值的闭包函数(生成器)

返回值:定义了“桩表达式”返回指定值的行为的 CardinalitySelector 对象实例

func returnsConsecutively
func returnsConsecutively(values: Array<R>): Continuation<R>

功能:定义“桩表达式”按列表顺序返回指定的值的行为。“桩表达式”将被调用多次,次数与数组内值的个数相同。

参数:

  • values: “桩表达式”的返回值列表

返回值:定义了“桩表达式”按序返回指定值的行为的 Continuation 对象实例

异常:

  • IllegalArgumentException 当参数列表为空时,抛出异常
func returnsConsecutively
func returnsConsecutively(values: ArrayList<R>): Continuation<R>

功能:定义“桩表达式”按列表顺序返回指定的值的行为。“桩表达式”将被连续调用多次,次数与数组列表内值的个数相同。

参数:

  • values: “桩表达式”的返回值列表

返回值:定义了“桩表达式”按序返回指定值的 Continuation 对象实例

异常:

  • IllegalArgumentException 当参数列表为空时,抛出异常
func throws
func throws(exception: Exception): CardinalitySelector<R>

功能:定义“桩表达式”抛出异常的行为。

参数:

  • exception: 预期“桩表达式”抛出的异常对象

返回值:定义了“桩表达式”抛出异常的行为的 CardinalitySelector 对象实例

func throws
func throws(exceptionFactory: () -> Exception): CardinalitySelector<R>

功能:定义“桩表达式”抛出异常的行为,异常由参数闭包函数生成。

参数:

  • exceptionFactory: 构造预期“桩表达式”抛出的异常对象的闭包函数(生成器)

返回值:定义了“桩表达式”抛出异常行为的 CardinalitySelector 对象实例

func fails
func fails(): Unit

功能:定义“桩表达式”抛出 AssertionException 异常的行为。

func callsOriginal(): CardinalitySelector
func callsOriginal(): CardinalitySelector<R>

功能:定义“桩表达式”执行原始代码逻辑的行为。

返回值:定义了“桩表达式”执行原始代码逻辑的 CardinalitySelector 对象实例

interface CardinalitySelector

public interface CardinalitySelector<R> {
    func anyTimes(): Unit
    func once(): Continuation<R>
    func atLeastOnce(): Unit
    func times(expectedTimes: Int64): Continuation<R>
    func times(min!: Int64, max!: Int64): Unit
    func atLeastTimes(minTimesExpected: Int64): Unit
}

此接口提供了可定义“桩表达式”的最近一次行为的执行次数的 API 。 该实例仅可被 ActionSelector<R> 的 API 生成(其中 R 代表“桩表达式”的返回类型)。例如:@On(foo.bar()).returns("Predefined value").atLeastOnce() 。 为方便表达,后文将“桩表达式”的最近一次行为称为“桩行为”。 此接口提供的 API 提供的验证能力如下:

  • “桩表达式”的调用次数超过指定次数将立即抛出 ExpectationFailedException
  • “桩表达式”的调用次数不足时,框架将在测试用例执行完成后抛出 ExceptionFailedException
func anyTimes
func anyTimes(): Unit

功能:定义“桩行为”可以执行任意次数。此函数对“桩表达式”的调用次数不做任何校验。

func once
func once(): Continuation<R>

功能:定义“桩行为”仅被执行一次。此函数将在验证“桩表达式”执行次数超出一次时,抛出异常。

返回值:定义了验证“桩行为”仅被执行一次的行为的 Continuation 对象实例

异常:

  • ExpectationFailedException: 验证“桩行为”执行次数超过一次时,立即抛出异常
func atLeastOnce
func atLeastOnce(): Unit

功能:定义“桩行为”最少被执行一次。验证不到一次时,抛出异常。

异常:

  • ExpectationFailedException: 验证“桩行为”执行次数不到一次时,抛出异常
func times
func times(expectedTimes: Int64): Continuation<R>

功能:定义“桩行为”被执行指定次数。验证不是指定次数时,抛出异常。

参数:

  • expectedTimes :预期“桩行为”被执行的次数

返回值:定义了验证“桩行为”被执行指定次数的行为的 Continuation 对象实例

异常:

  • ExpectationFailedException: 验证“桩行为”执行次数不是指定次数时,抛出异常
func times
func times(min!: Int64, max!: Int64): Unit

功能:定义“桩行为”执行指定次数范围。验证超出指定次数范围时,抛出异常。

参数:

  • min :预期“桩行为”被执行的最小次数
  • max :预期“桩行为”被执行的最大次数

异常:

  • ExpectationFailedException: 验证“桩行为”执行次数不是指定次数范围时,抛出异常
func atLeastTimes
func atLeastTimes(minTimesExpected: Int64): Unit

功能:定义“桩行为”最少被执行指定次数的行为。验证实际执行次数低于最少指定次数时,抛出异常。

参数:

  • minTimesExpected :预期“桩行为”最少被执行的次数

异常:

  • ExpectationFailedException: 验证“桩行为”执行少于指定次数时,抛出异常

interface ContinuationSelector

public interface Continuation<R> {
    func then(): ActionSelector<R>
}

此接口提供了可继续定义“桩表达式”的行为的 API 。 该实例可由ActionSelector<R>CardinalitySelector<R> 的 API 调用后生成。 此接口提供的接口能力如下:

  • 允许当先前的操作得到满足时,“桩表达式”将执行额外的操作。仅当后面跟着一个行为定义时,Continuation 实例才有意义。
  • 当先前的操作未得到满足时,将抛出 MockFrameworkException 异常。并不保证抛出此异常的确切位置。
func then
func then(): ActionSelector<R>

功能: 当链中的先前操作完成时,返回 ActionSelector 对象。

返回值:ActionSelector 对象实例

异常 MockFrameworkException:当先前的操作未得到满足时,将抛出异常。

参数匹配器

class Matchers
public class Matchers {
    public static func argThat<T>(predicate: (T) -> Bool): TypedMatcher<T>
    public static func argThatNot<T>(predicate: (T) -> Bool): TypedMatcher<T> 
    public static func same<T>(target: T): TypedMatcher<T> where T <: Object
    public static func eq<T>(target: T): TypedMatcher<T> where T <: Equatable<T>
    public static func ofType<T>(): TypedMatcher<T>
    public static func any(): AnyMatcher
    public static func default<T>(target: T): TypedMatcher<T>
}

该类提供生成匹配器的静态函数。匹配器对象仅可通过此处的静态函数生成。匹配器可在 Stubs 链中使用。 例如:@On(foo.bar(ofType<Int64>())).returns(1)

func argThat
public static func argThat<T>(predicate: (T) -> Bool): TypedMatcher<T>

功能:根据提供的过滤器闭包过滤输入值。

参数:

  • predicate : 过滤器

返回值:参数过滤类型匹配器实例

func argThatNot
public static func argThatNot<T>(predicate: (T) -> Bool): TypedMatcher<T>

功能:根据提供的过滤器闭包,满足 'predicate(value) == false' 时过滤输入值。

参数:

  • predicate : 过滤器

返回值:参数过滤类型匹配器实例

func same
public static func same<T>(target: T): TypedMatcher<T> where T <: Object

功能:根据与所提供对象的引用相等性来过滤输入值。

参数:

  • target : 匹配对象

返回值:仅允许与给定对象引用相等的参数的参数匹配器

func eq
public static func eq<T>(target: T): TypedMatcher<T> where T <: Equatable<T>

功能:根据与提供的值的结构相等性过滤输入值。

参数:

  • target : 匹配对象

返回值:仅允许结构上等于给定值的参数匹配器

func ofType
public static func ofType<T>(): TypedMatcher<T>

功能:根据类型过滤输入值。

参数:

  • target : 匹配对象

返回值:仅允许特定类型的类型匹配器

func any()
public static func any(): AnyMatcher

功能:允许将任何值作为参数。

返回值:允许任意值的参数匹配器

func default
public static func default<T>(target: T): TypedMatcher<T>

功能:根据结构(更高优先级)或引用相等性来匹配值。如果传入的参数既不是 Equatable<T> 也不是引用类型,则会在运行时抛出异常(编译期不做检查)。

参数:

  • target : 必须通过结构或引用相等来匹配的匹配对象

返回值:默认类型匹配器

异常:

  • MockFrameworkException : 如果参数 target 既不是 Equatable<T> 类型也不是引用类型,则抛出异常

macro On

public macro On(tokens: Tokens): Tokens

@On 宏调用表达式创建了“桩表达式”的“桩行为”定义的表达式链的头。 @On 的参数即为“桩表达式”,由 mock objectspy object 的引用表达式、其成员函数的调用表达式,以及参数匹配器(用于描述该“桩表达式”接受哪些参数,仅可为对 Matchers 类的静态函数的调用表达式)组成。

参数:

  • input :符合 @On 语法规则定义的 Tokens

返回值:被框架处理后的 Tokens

异常:

  • MockFrameworkException : 当“桩行为”执行出错时,将抛出异常

行为验证

class Verify

public class Verify {
    public static func that(statement: VerifyStatement): Unit
    public static func unordered(exhaustive: Exhaustiveness, collectStatements: (UnorderedVerifier) -> Unit): Unit
    public static func unordered(collectStatements: (UnorderedVerifier) -> Unit): Unit
    public static func unordered(statements: Array<VerifyStatement>): Unit
    public static func unordered(exhaustive: Exhaustiveness, statements: Array<VerifyStatement>): Unit
    public static func ordered(collectStatements: (OrderedVerifier) -> Unit): Unit
    public static func ordered(statements: Array<VerifyStatement>): Unit
    public static func clearInvocationLog(): Unit
    public static func noInteractions(mocks: Array<Object>): Unit
}

Verify 提供了一系列静态方法来支持定义所需验证的动作,如 thatordered 以及 unorder 。 一个验证动作可以包含多个由 @Called 生成的“动作语句”,来描述需要验证的动作。 通常验证的范围为所在测试用例的函数体,但 Verify 提供了 clearInvocationLog 函数来清除此前的执行记录,以缩小验证范围。

func that
public static func that(statement: VerifyStatement): Unit

验证是否正确执行了传入的单个“动作语句”。

参数:

  • statement :所需验证的“动作语句”

异常:

  • VerificationFailedException :验证不通过时,将抛出异常
func unordered
public static func unordered(statements: Array<VerifyStatement>): Unit

此函数支持验证“动作语句”是否被执行或执行的次数是否符合定义,并且不校验执行顺序。默认情况下,“动作语句”的执行次数为至少一次。 传入列表中的“动作语句”必须是不相交的(即当单个调用行为,可以匹配多个“动作语句”时,将抛出异常)。 验证模式为 exhaustive (全量匹配,验证范围内的所有执行情况都应在验证动作中被指定)

举例来说:

let foo = mock<Foo>()
for (i in 0..4) {
    foo.bar(i % 2)
}

// 验证 bar() 在传入参数为 0 或 1 的情况下均至少执行一次
Verify.unordered(
    @Called(foo.bar(0)),
    @Called(foo.bar(1))
)

// 此处的验证动作将抛出异常,因为 `foo.bar(_)` 包含了 `foo.bar(1)`
Verify.unordered(
    @Called(foo.bar(_)).times(2),
    @Called(foo.bar(1)).times(2)
)
// 可以通过如下方式进行验证
// 验证入参为 1 的调用表达式执行了2次
Verify.that(@Called(foo.bar(1)).times(2))
// 验证任意入参的调用表达式执行了2次
Verify.that(@Called(foo.bar(_)).times(2)) // called four times in total

参数:

  • statements :待验证的多条“动作语句”,变长参数语法支持参数省略 []

异常:

  • VerificationFailedException :验证不通过时,抛出异常
func unordered
public static func unordered(exhaustive: Exhaustiveness, statements: Array<VerifyStatement>): Unit

此函数支持验证“动作语句”是否被执行或执行的次数是否符合定义,并且不校验执行顺序。默认情况下,“动作语句”的执行次数为至少一次。 传入列表中的“动作语句”必须是不相交的(即当单个调用行为,可以匹配多个“动作语句”时,将抛出异常)。

参数:

  • statements :待验证的多条“动作语句”,变长参数语法支持参数省略 []
  • exhaustive :验证模式,详见《 enum Exhaustiveness 》章节

异常:

  • VerificationFailedException :验证不通过时,抛出异常
func unordered
public static func unordered(collectStatements: (UnorderedVerifier) -> Unit): Unit

此函数支持验证“动作语句”是否被执行或执行的次数是否符合定义,并且不校验执行顺序。默认情况下,“动作语句”的执行次数为至少一次。 传入列表中的“动作语句”必须是不相交的(即当单个调用行为,可以匹配多个“动作语句”时,将抛出异常)。 验证模式为 exhaustive (全量匹配,验证范围内的所有执行情况都应在验证动作中被指定) “动作语句”通过入参中的闭包动态增加。举例来说:


let totalTimes = getTimes()
for (i in 0..totalTimes) {
    foo.bar(i % 2)
}
// 通过闭包使得“动作语句”可以通过 totalTimes 的值确定内容
Verify.unordered { v =>
    for (j in 0..totalTimes) {
        v.checkThat(@Called(foo.bar(eq(j % 2))))
    }
}

参数:

  • collectStatements :支持可动态增加“动作语句”的闭包

异常:

  • VerificationFailedException :验证不通过时,抛出异常
func unordered
public static func unordered(exhaustive: Exhaustiveness, collectStatements: (UnorderedVerifier) -> Unit): Unit

此函数支持验证“动作语句”是否被执行或执行的次数是否符合定义,并且不校验执行顺序。默认情况下,“动作语句”的执行次数为至少一次。 传入列表中的“动作语句”必须是不相交的(即当单个调用行为,可以匹配多个“动作语句”时,将抛出异常)。 “动作语句”通过入参中的闭包动态增加。

参数:

  • collectStatements :支持可动态增加“动作语句”的闭包
  • exhaustive :验证模式,详见《 enum Exhaustiveness 》章节

异常:

  • VerificationFailedException :验证不通过时,抛出异常
func ordered
public static func ordered(statements: Array<VerifyStatement>): Unit

此函数支持验证“动作语句”是否被执行或执行的次数是否符合定义,并且校验执行顺序。默认情况下,“动作语句”的执行次数为一次。 传入列表中的“动作语句”必须是不相交的(即当单个调用行为,可以匹配多个“动作语句”时,将抛出异常)。 验证模式为 exhaustive (全量匹配,验证范围内的所有执行情况都应在验证动作中被指定)

举例来说:

for (i in 0..4) {
    foo.bar(i % 2)
}

Verify.ordered(
    @Called(foo.bar(0)),
    @Called(foo.bar(1)),
    @Called(foo.bar(0)),
    @Called(foo.bar(1)),
)

// 将抛出异常,验证范围内有 4 次 foo.bar() 表达式的执行动作,此处只验证了2次执行。
Verify.ordered(
    @Called(foo.bar(0)),
    @Called(foo.bar(_)),
)
func ordered
public static func ordered( collectStatements: (OrderedVerifier) -> Unit): Unit

此函数支持验证“动作语句”是否被执行或执行的次数是否符合定义,并且校验执行顺序。默认情况下,“动作语句”的执行次数为一次。 传入列表中的“动作语句”必须是不相交的(即当单个调用行为,可以匹配多个“动作语句”时,将抛出异常)。 “动作语句”通过入参中的闭包动态增加。 验证模式为 exhaustive (全量匹配,验证范围内的所有执行情况都应在验证动作中被指定)

参数:

  • collectStatements :支持可动态增加“动作语句”的闭包

异常:

  • VerificationFailedException :验证不通过时,抛出异常
func noInteractions
public static func noInteractions(mocks: Array<Object>): Unit

在验证范围内,对象没有任何执行动作时,验证通过。

参数:

  • mocks :被验证的对象列表

异常

  • VerificationFailedException :验证不通过时,抛出异常
func clearInvocationLog
public static func clearInvocationLog(): Unit

清除前序的执行记录,以缩小验证范围。

enum Exhaustiveness

public enum Exhaustiveness {
    Exhaustive | Partial
}

此枚举类型用于指定 unordered 函数的验证模式,包含两种模式。 Exhaustive 模式要求对于验证范围内的所有“桩表达式”,均需在验证动作中定义。 Partial 模式的要求较松,可以忽略“桩表达式”在验证范围内未被验证动作定义的执行行为。

举例来说:

for (i in 0..6) {
    foo.bar(i % 3)
}

// 此处验证动作将抛出异常,因为 foo.bar()在验证范围内一共执行了 6 次,而此处的验证动作仅指定了 4 次执行行为。
Verify.unordered(
    @Called(foo.bar(1)).times(2),
    @Called(foo.bar(2)).times(2)
)

// 此处验证动作可以成功,指定了 Partial 模式后,2 次未在验证动作中定义的执行行为将被忽略。
Verify.unordered(Partial,
    @Called(foo.bar(1)).times(2),
    @Called(foo.bar(2)).times(2)
)
Exhaustive

要求在验证范围内的每一次“桩表达式”的调用均需在验证动作中被定义。

Partial

允许验证范围内存在未在验证动作中被定义的“桩表达式”的调用行为。

class UnorderedVerifier

public class UnorderedVerifier{
    public func checkThat(statement: VerifyStatement):UnorderedVerifier
}

此类型用于收集 “动作语句”, 可在 unordered 函数中动态传入验证行为。

func checkThat
public func checkThat(statement: VerifyStatement):UnorderedVerifier

添加一条 “动作语句”。

参数:

  • statement:待被添加的“动作语句”

返回值:

  • UnorderedVerifier : 返回对象自身

class OrderedVerifier

public class OrderedVerifier {
    public func checkThat(statement: VerifyStatement): OrderedVerifier
}

此类型用于收集 “动作语句”, 可在 ordered 函数中动态传入验证行为。

func checkThat
public func checkThat(statement: VerifyStatement): OrderedVerifier

添加一条 “动作语句”。

参数:

  • statement:待被添加的“动作语句”

返回值:

  • OrderedVerifier : 返回对象自身

class VerifyStatement

public class VerifyStatement {
    public func once(): VerifyStatement
    public func atLeastOnce(): VerifyStatement
    public func times(expectedTimes: Int64): VerifyStatement
    public func times(min!: Int64, max!: Int64): VerifyStatement
    public func atLeastTimes(minTimesExpected: Int64): VerifyStatement
    public func never(): VerifyStatement
}

此类型表示对“桩表达式”在验证范围内的单个验证动作语句(即上文中的“动作语句”),提供了成员函数指定“桩表达式”的执行次数。 该类型的对象仅可通过 @Called 宏调用表达式创建。 对一个对象连续调用多个成员函数没有意义,并且会抛出异常。即,执行次数仅可被指定一次。 当未调用成员函数指定执行次数时,将基于语句所在的验证动作类型定义默认的执行次数验证值。例如在 Verify.ordered() 中的“动作语句”默认为验证执行一次。

func once
public func once(): VerifyStatement

指定此“动作语句”验证在验证范围内“桩表达式”仅被执行一次

返回值:

  • VerifyStatement :返回对象自身

异常:

  • MockFrameworkException : 当对象已被指定过执行次数或已被传入过“验证动作”中时,将抛出异常
func atLeastOnce
public func atLeastOnce(): VerifyStatement

指定此“动作语句”验证在验证范围内“桩表达式”最少被执行一次

返回值:

  • VerifyStatement :返回对象自身

异常:

  • MockFrameworkException : 当对象已被指定过执行次数或已被传入过“验证动作”中时,将抛出异常
func times
public func times(expectedTimes: Int64): VerifyStatement

指定此“动作语句”验证在验证范围内“桩表达式”被执行指定次数。

参数:

  • expectedTimes :预期验证的执行次数

返回值:

  • VerifyStatement :返回对象自身

异常:

  • MockFrameworkException : 当对象已被指定过执行次数或已被传入过“验证动作”中时,将抛出异常
func times
public func times(min!: Int64, max!: Int64): VerifyStatement

指定此“动作语句”验证在验证范围内“桩表达式”的执行次数在指定范围内。

参数:

  • min :预期验证的最小执行次数
  • max :预期验证的最大执行次数

返回值:

  • VerifyStatement :返回对象自身

异常:

  • MockFrameworkException : 当对象已被指定过执行次数或已被传入过“验证动作”中时,将抛出异常
func atLeastTimes
public func atLeastTimes(minTimesExpected: Int64): VerifyStatement

指定此“动作语句”验证在验证范围内“桩表达式”最少执行指定的次数。

参数:

  • minTimesExpected :预期验证的执行最少次数

返回值:

  • VerifyStatement :返回对象自身

异常:

  • MockFrameworkException : 当对象已被指定过执行次数或已被传入过“验证动作”中时,将抛出异常
func never
public func never(): VerifyStatement

指定此“动作语句”验证在验证范围内“桩表达式”不会被执行

返回值:

  • VerifyStatement :返回对象自身

异常:

  • MockFrameworkException : 当对象已被传入过“验证动作”中时,将抛出异常

macro Called

public macro Called(tokens: Tokens): Tokens

创建一个“动作语句”对象。宏调用表达式的入参的语法要求和 @On 相同。详见《 macro On 》章节。

值监听器与参数捕获器

interface ValueListener

public interface ValueListener<T> {
    func lastValue(): Option<T>
    func allValues(): Array<T>
    func addCallback(callback: (T) -> Unit): Unit
    static func new(): ValueListener<T>
    static func onEach(callback: (T) -> Unit): ValueListener<T>
}

此接口提供了多个成员函数以支持“监听”传入给“桩表达式”的参数,即对每次调用中传入“桩表达式”的参数进行指定的操作( addCallback()onEach 中的闭包函数即为对参数进行的操作内容)。 一般与参数匹配器生成函数 argThat 或者 capture 配合使用。

func lastValue
func lastValue(): Option<T>

返回当前“值监听器”对象所处理的最后一个值。

返回值:

  • Option :返回“值监听器”对象所处理的最后一个值,不存在时,返回 None
func allValues
func allValues(): Array<T>

返回当前“值监听器”对象已所处理的所有值。

返回值:

  • Array :返回“值监听器”对象所处理的所有值列表
func addCallback
func addCallback(callback: (T) -> Unit): Unit

为当前“值监听器”对象增加闭包函数,该函数将处理传入的参数值。

参数:

  • callback :处理参数值的闭包函数
func new
static func new(): ValueListener<T>

创建一个新的“值监听器”对象,不包含任何处理参数的闭包方法。

返回值:

  • ValueListener :“值监听器”对象
func onEach
static func onEach(callback: (T) -> Unit): ValueListener<T>

创建一个新的“值监听器”对象,带有一个处理参数的闭包方法。

返回值:

  • ValueListener :“值监听器”对象

参数:

  • callback :处理参数值的闭包函数

class Matchers

public class Matchers {
    public static func argThat<T>(listener: ValueListener<T>, predicate: (T) -> Bool): TypedMatcher<T>
    public static func capture<T>(listener: ValueListener<T>): TypedMatcher<T>
}

此处增加列举 Matcher 类两个可传入“值监听器”的静态函数,可用于生成带有值监听器的参数匹配器,其他函数说明详见 《行为定义》章节中《参数匹配器》章节里的《 class Matchers 》章节。

func argThat
public static func argThat<T>(listener: ValueListener<T>, predicate: (T) -> Bool): TypedMatcher<T>

通过传入的 predicate 闭包函数过滤传入的参数值,允许 listener 值监听器对满足条件的传入参数值进行处理。

参数:

  • listener :值监听器
  • predicate :过滤器,可通过此函数定义过滤参数值的匹配条件

返回值:

  • TypedMatcher :拥有值监听器和过滤器的类型匹配器
func capture
public static func capture<T>(listener: ValueListener<T>): TypedMatcher<T>

允许 listener 值监听器对类型为 T 的传入参数值进行处理。当 capture 的类型参数未指定时,将使用值监听器的类型参数值。

参数:

  • listener :值监听器

返回值:

  • TypedMatcher :拥有值监听器的类型匹配器

注意:值监听器不允许在 @Called 的参数范围内使用。

附录

API list

在框架中,部分 API 由于整体实现结构要求,属性为对外可见,但用户不应直接使用如下 API 。因此此处仅列举 API 列表,而不详细说明对应 API 使用方式。

package unittest.mock

public abstract class ArgumentMatcher {
    public func withDescription(description: String): ArgumentMatcher
    public func forParameter(name: String): ArgumentMatcher
    public func matchesAny(arg: Any): Bool
}
public abstract class TypedMatcher<T> <: ArgumentMatcher {
    public func matches(arg: T): Bool
    public override func matchesAny(arg: Any): Bool
    public override func matches(arg: T): Bool
    public prop valueListener: Option<ListenerInternal> 
}
public class AnyMatcher <: ArgumentMatcher {
    public func matchesAny(_: Any)
}
extend TypedMatcher<T> {
    public func value(): T
}
extend AnyMatcher {
    public func value<T>(): T
}

public class ConfigureMock {
    public static func stub<T, R>
}

public abstract class PrettyException <: Exception & PrettyPrintable {
    public func pprint(to: PrettyPrinter): PrettyPrinter
}
public class MockFrameworkInternalError <: PrettyException
public class MockFrameworkException <: PrettyException 
public open class ExpectationFailedException <: PrettyException 
public class UnnecessaryStubbingException <: PrettyException
public class UnstubbedInvocationException <: PrettyException 
public class UnhandledCallException <: PrettyException
public class VerificationFailedException <: PrettyException
 
public class MockFramework {
    public static func openSession(name!: String): Unit
    public static func openSession(): Unit
    public static func closeSession(verifyExpectations!: Bool = true): Unit
    public func onCall(call: Call): OnCall
}

@Intrinsic
public unsafe func createMock<T>(handler: CallHandler): T

@Intrinsic
public unsafe func createSpy<T>(handler: CallHandler, objectToSpyOn: T): T

public interface CallHandler {
    func onCall(call: Call): OnCall
}

public enum OnCall {
    ReturnZero | Return(Any) | Throw(Exception) | CallBase | ReturnDefault
}

public struct Call {
    public Call(
        public let funcInfo: FuncInfo,
        public let receiver: Object,
        public let args: Array<Any>
    ) {}
}

public struct FuncInfo {
    public FuncInfo(
        public let id: DeclId,
        public let params: Array<ParameterInfo>,
        public let hasImplementation: Bool,
        public let location: (String, Int64, Int64),
        public let outerDeclId: DeclId
    ) {}
}

public struct ParameterInfo {
    public ParameterInfo(
        public let name: String,
        public let position: Int64,
        public let isNamed: Bool,
        public let hasDefaultValue: Bool
    ) {}
}

public struct DeclId <: Equatable<DeclId> & Hashable {
    public DeclId(
        public let mangledName: String,
        public let shortName: String
    )
    public operator func ==(that: DeclId): Bool
    public operator func !=(that: DeclId): Bool
    public func hashCode(): Int64
}

public class NoneMatcher <: ArgumentMatcher {
    public override func matchesAny(arg: Any): Bool
}
extend Matchers {
    public static func none(): NoneMatcher
}
extend NoneMatcher {
    public func value<T>(): Option<T>
}

public class VerifyStatement {
    public static func fromStub<T, R> (
        stubCall: () -> R,
        matchers: Array<ArgumentMatcher>,
        objectReference: T,
        objectName: String,
        declarationName: String,
        callDescription: String,
        lineNumber: Int64
    ): VerifyStatement  // users should not use this API directly
}

public enum MockSessionKind {
    | Forbidden
    | Stateless
    | Verifiable
}

public sealed class ActionSelector {
    public func fails(): Unit
}
public sealed class MethodActionSelector<TRet> <: ActionSelector {
    public func throws(exception: Exception): CardinalitySelector<MethodActionSelector<TRet>>
    public func throws(exceptionFactory: () -> Exception): CardinalitySelector<MethodActionSelector<TRet>>
    public func returns(value: TRet): CardinalitySelector<MethodActionSelector<TRet>>
    public func returns(valueFactory: () -> TRet): CardinalitySelector<MethodActionSelector<TRet>>
    public func returnsConsecutively(values: Array<TRet>): Continuation<MethodActionSelector<TRet>>
    public func returnsConsecutively(values: ArrayList<TRet>): Continuation<MethodActionSelector<TRet>>
    public func callsOriginal(): CardinalitySelector<MethodActionSelector<TRet>>
}
public sealed class GetterActionSelector<TRet> <: ActionSelector {
    public func throws(exception: Exception): CardinalitySelector<GetterActionSelector<TRet>> 
    public func throws(exceptionFactory: () -> Exception): CardinalitySelector<GetterActionSelector<TRet>> 
    public func returns(value: TRet): CardinalitySelector<GetterActionSelector<TRet>> 
    public func returns(valueFactory: () -> TRet): CardinalitySelector<GetterActionSelector<TRet>>
    public func returnsConsecutively(values: Array<TRet>): Continuation<GetterActionSelector<TRet>> 
    public func returnsConsecutively(values: ArrayList<TRet>): Continuation<GetterActionSelector<TRet>> 
    public func getsOriginal(): CardinalitySelector<GetterActionSelector<TRet>> 
    public func getsField(field: SyntheticField<TRet>): CardinalitySelector<GetterActionSelector<TRet>>
}
public sealed class SetterActionSelector<TArg> <: ActionSelector {
    public func throws(exception: Exception): CardinalitySelector<SetterActionSelector<TArg>> 
    public func throws(exceptionFactory: () -> Exception): CardinalitySelector<SetterActionSelector<TArg>> 
    public func doesNothing(): CardinalitySelector<SetterActionSelector<TArg>>
    public func setsOriginal(): CardinalitySelector<SetterActionSelector<TArg>> 
    public func setsField(field: SyntheticField<TArg>): CardinalitySelector<SetterActionSelector<TArg>>
    public func returns(): CardinalitySelector<MethodActionSelector<TRet>>
}



public interface ValueListener<T> {
    public override func supplyValue(value: Any)
}

public class ConfigureMock {
    public static func stubMethod<TObj, TRet>(
        stubCall: () -> TRet,
        matchers: Array<ArgumentMatcher>,
        objectReference: TObj,
        objectName: String,
        methodName: String,
        callDescription: String,
        lineNumber: Int64
    ): MethodActionSelector<TRet>

    public static func stubGetter<TObj, TRet>(
        stubCall: () -> TRet,
        objectReference: TObj,
        objectName: String,
        fieldOrPropertyName: String,
        callDescription: String,
        lineNumber: Int64
    ): GetterActionSelector<TRet>

    public static func stubSetter<TObj, TArg>(
        stubCall: () -> Unit,
        _: () -> TArg, // capturing type of property/field
        matcher: ArgumentMatcher,
        objectReference: TObj,
        objectName: String,
        fieldOrPropertyName: String,
        callDescription: String,
        lineNumber: Int64
    ): SetterActionSelector<TArg>
}

public class SyntheticField<T> {
    SyntheticField(let description: SyntheticFieldDescription)
    public static func create(initialValue!: T): SyntheticField<T>
    @OverflowWrapping
    public func hashCode(): Int64
    public operator func ==(that: AutoFieldId): Bool
    public operator func !=(that: AutoFieldId): Bool
}

public class CardinalitySelector<A> where A <: ActionSelector{
    public func anyTimes(): Unit 
    public func once(): Continuation<A> 
    public func atLeastOnce(): Unit 
    public func times(expectedTimes: Int64): Continuation<A> 
    public func times(min!: Int64, max!: Int64): Unit 
    public func atLeastTimes(minTimesExpected: Int64): Unit
}
public class Continuation<A> where A <: ActionSelector {
    public func then(): A
}

public enum DeclKind {
    | Method(/*name:*/ String) 
    | FieldGetter(/*fieldName: */String, /*hasSetter: */Bool) 
    | FieldSetter(/*fieldName:*/ String) 
    | PropertyGetter(/*propertyName:*/String, /*hasSetter:*/ Bool) 
    | PropertySetter(/*propertyName:*/ String)
}


public interface HasDefaultValueForStub<T> {
    static func defaultValueForStub(): T
}
extend Unit <: HasDefaultValueForStub<Unit>
extend Int8 <: HasDefaultValueForStub<Int8> 
extend Int16 <: HasDefaultValueForStub<Int16> 
extend Int32 <: HasDefaultValueForStub<Int32> 
extend Int64 <: HasDefaultValueForStub<Int64> 
extend Float16 <: HasDefaultValueForStub<Float16>
extend Float32 <: HasDefaultValueForStub<Float32> 
extend Float64 <: HasDefaultValueForStub<Float64>
extend Bool <: HasDefaultValueForStub<Bool>
extend String <: HasDefaultValueForStub<String>
extend Option<T> <: HasDefaultValueForStub<Option<T>>
extend Array<T> <: HasDefaultValueForStub<Array<T>>
extend ArrayList<T> <: HasDefaultValueForStub<ArrayList<T>>
extend HashSet<T> <: HasDefaultValueForStub<HashSet<T>>
extend HashMap<K, V> <: HasDefaultValueForStub<HashMap<K, V>>

public class IllegalMockCallException <: Exception
public class NoDefaultValueForMockException <: Exception
public class MockReturnValueTypeMismatchException <: Exception