测试已测试 | ✓ |
Lang语言 | SwiftSwift |
许可证 | MIT |
发布上次发布 | 2016年8月 |
SPM支持SPM | ✗ |
维护者:Jóhann Þorvaldur Bergþórsson。
MockItYourself
是为Swift创建模拟框架的尝试。在Swift中目前不能动态创建类,因此无法创建类似OCMock这样的强大模拟框架。MockItYourself
是减少手动创建模拟所需的冗余代码的尝试。
MockItYourself
受到了SwiftMock的很大启发,从某些方面来看,可以被视为该项目的分支。
MockItYourself可以通过CocoaPods获取。要安装,只需将以下行添加到您的Podfile中:
source 'https://github.com/CocoaPods/Specs.git'
use_frameworks!
target 'MyApp' do
end
target 'MyApp_Tests', :exclusive => true do
pod 'MockItYourself', '1.0.0'
end
在Swift中模拟依赖项的标准方式是手动创建自己的模拟
class Dependency {
func slowAndExpensiveMethod(arg1: String, arg2: Int) -> Double {
print("Do something really slow and expensive with arguments")
return 40.0
}
}
class MockDependency: Dependency {
var didCallSlowAndExpensiveMethod: Bool = false
var lastCalledArg1: String?
var lastCalledArg2: Int?
override func slowAndExpensiveMethod(arg1: String, arg2: Int) -> Double {
didCallSlowAndExpensiveMethod = true
lastCalledArg1 = arg1
lastCalledArg2 = arg2
return 50.0
}
}
struct ObjectUnderTests {
let dependency: Dependency
func method() -> Double {
let result = dependency.slowAndExpensiveMethod("A", arg2: 1)
return result / 2
}
}
class MockExampleTests: XCTestCase {
var mockDependency: MockDependency!
var objectUnderTest: ObjectUnderTests!
override func setUp() {
mockDependency = MockDependency()
objectUnderTest = ObjectUnderTests(dependency: mockDependency)
}
func test_did_call_method_on_dependency_with_correct_arguments() {
let _ = objectUnderTest.method()
XCTAssert(mockDependency.didCallSlowAndExpensiveMethod)
XCTAssertEqual(mockDependency.lastCalledArg1, "A")
XCTAssertEqual(mockDependency.lastCalledArg2, 1)
}
func test_method_returns_correct_result_given_dependency_returns_50() {
let result = objectUnderTest.method()
XCTAssertEqual(result, 25.0)
}
}
这很快变得繁琐,而MockItYourself
是减少冗余代码的尝试。
class Dependency {
func slowAndExpensiveMethod(arg1: String, arg2: Int) -> Double {
print("Do something really slow and expensive with arguments")
return 40.0
}
}
class MockDependency: Dependency, MockItYourself {
let callHandler = MockCallHandler()
override func slowAndExpensiveMethod(arg1: String, arg2: Int) -> Double {
return callHandler.registerCall(args: Args2(arg(arg1), arg(arg2)), defaultReturnValue: 50) as! Double
}
}
struct ObjectUnderTests {
let dependency: Dependency
func method() -> Double {
let result = dependency.slowAndExpensiveMethod("A", arg2: 1)
return result / 2
}
}
class MockExampleTests: XCTestCase {
var mockDependency: MockDependency!
var objectUnderTest: ObjectUnderTests!
override func setUp() {
mockDependency = MockDependency()
objectUnderTest = ObjectUnderTests(dependency: mockDependency)
}
func test_did_call_method_on_dependency_with_correct_arguments() {
let _ = objectUnderTest.method()
verify(mockDependency) { self.mockDependency.slowAndExpensiveMethod("A", arg2: 1) }
}
func test_method_returns_correct_result_given_dependency_returns_50() {
stub(mockDependency, andReturnValue: 50) { mockDependency.slowAndExpensiveMethod("A", arg2: 1) }
let result = objectUnderTest.method()
XCTAssertEqual(result, 25.0)
}
}
MockItYourself
帮助减少手动创建模拟时的冗余代码。让我们假设我们有以下类:
class Dependency {
func slowAndExpensiveMethod(arg1: String, arg2: Int) -> Double {
return 40.0
}
}
创建模拟很简单
Dependency
的子类。callHandler
属性来实现MockItYourself
协议。import MockItYourself
class MockDependency: Dependency, MockItYourself {
let callHandler = MockCallHandler()
override func slowAndExpensiveMethod(arg1: String, arg2: Int) -> Double {
return callHandler.registerCall(args: Args2(arg(arg1), arg(arg2)), defaultReturnValue: 50)
}
}
MockItYourself
允许您通过检查您的模拟上的方法是否调用来验证:
验证方法被调用
func test_verify() {
mock.slowAndExpensiveMethod("A", arg2: 1)
verify(mock) { self.mock.slowAndExpensiveMethod(any(), arg2: any()) }
}
验证方法被调用n次
func test_verify_number_of_calls() {
mock.slowAndExpensiveMethod("A", arg2: 1)
mock.slowAndExpensiveMethod("A", arg2: 1)
verify(mock, expectedCallCount: 2) { self.mock.slowAndExpensiveMethod(any(), arg2: any()) }
}
验证方法被调用,并且传递了特定的参数
func test_verify_with_arguments() {
mock.slowAndExpensiveMethod("A", arg2: 1)
verify(mock, checkArguments: true) { self.mock.slowAndExpensiveMethod("A", arg2: 1) }
}
验证方法没有被调用
func test_reject() {
reject(mock) { self.mock.slowAndExpensiveMethod("A", arg2: 1) }
}
存根方法或属性的返回值
func test_stubbing() {
stub(mock, andReturnValue: 30) { self.mock.slowAndExpensiveMethod("A", arg2: 1) }
let returnValue = mock.slowAndExpensiveMethod("A", arg2: 1)
XCTAssertEqual(returnValue, 30)
}
MockItYourself 在MIT许可证下提供。更多信息请参阅LICENSE文件。