Swift 的简单依赖注入框架
用法
- 创建一个协议
protocol AnimalSound {
func makeSound() -> String
}
- 为协议添加实现
class CatViewModel: AnimalSound {
func makeSound() -> String{
return "meow"
}
}
- 在您想使用依赖注入的类中添加静态变量。请记住将协议类型用作
Injection
类型。
static let viewModelInjection = Injection<AnimalSound>(CatViewModel())
- 注入依赖项
let viewModel = viewModelInjection.inject()
- 如果您想使用不同的视图模型对象,请使用以下内容
ViewController.viewModelInjection.overrideOnce = { MockAnimalSound() }
(其中 MockAnimalSound
必须实现 AnimalSound
协议)
安装
使用 CocoaPods。
将其添加到 Podfile 中
pod 'InjectStory'
然后调用
pod install
和导入
import InjectStory
示例
// ViewController.swift
import UIKit
import InjectStory
class ViewController: UIViewController {
static let viewModelInjection = Injection<AnimalSound>(CatViewModel())
let viewModel = viewModelInjection.inject()
override func viewDidLoad() {
super.viewDidLoad()
soundLabel.text = viewModel.makeSound()
}
@IBOutlet weak var soundLabel: UILabel!
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
// CatViewModel.swift
import Foundation
protocol AnimalSound {
func makeSound() -> String
}
class CatViewModel: AnimalSound {
func makeSound() -> String{
return "meow"
}
}
// ViewControllerTests.swift
import XCTest
@testable import YourApp
class ViewControllerTests: XCTestCase {
func testIfViewControllerCallsMeowMethod() {
//given
let spy = AnimalSoundSpy()
//override value returned by viewModelInjection
ViewController.viewModelInjection.overrideOnce = { spy }
//create system under test
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let sut = storyboard.instantiateViewController(withIdentifier: "viewController") as! ViewController
//when
_ = sut.view //to call viewDidLoad
//then
XCTAssertTrue(spy.makeSoundCalled)
}
}
//mock class
class AnimalSoundSpy: AnimalSound {
var makeSoundCalled = false
func makeSound() -> String{
makeSoundCalled = true
return ""
}
}