我正在编写一些单元测试,我需要创建一个GIDGoogleUser的模拟实例,以确保我的API返回我的模型User类的正确实例,该实例是GIDGoogleUser中字段的子集。
由于GIDGoogleUser不公开初始化程序,并且其所有属性都是只读的,因此我无法创建模拟实例并将其注入到转换器中。有什么办法可以做到?
为简单起见,这就是我正在做的事情:
struct User {
let name: String
init(googleUser: GIDGoogleUser) {
name = googleUser.profile.name
}
}
我不确定您说不能嘲笑GIDGoogleUser
时的意思。这是我刚才制作的GIDGoogleUser
的模拟图片:
首先,声明GIDGoogleUser
和GIDProfileData
将遵循的协议,以及我们稍后将进行的模拟:
protocol GoogleUserProtocol {
associatedtype Profile: ProfileDataProtocol
var profile: Profile! { get }
}
protocol ProfileDataProtocol {
var name: String! { get }
}
然后,使GIDGoogleUser
和GIDProfileData
符合以下协议:
extension GIDGoogleUser: GoogleUserProtocol {}
extension GIDProfileData: ProfileDataProtocol {}
然后,创建我们的模拟类(或本例中我选择的结构),并使它们符合上述协议:
struct MockGoogleUser: GoogleUserProtocol {
let profile: MockProfileData!
}
struct MockProfileData: ProfileDataProtocol {
let name: String!
}
最后,将User
的初始化程序调整为不使用GIDGoogleUser
,而是使用任何符合GoogleUserProtocol
的内容:
struct User {
let name: String
init<G>(googleUser: G) where G: GoogleUserProtocol {
name = googleUser.profile.name
}
}
这将使您创建模拟的Google User实例并将其注入到User
中,如下所示:
let mockProfileData = MockProfileData(name: "Mock User Name")
let mockGoogleUser = MockGoogleUser(profile: mockProfileData)
let mockUser = User(googleUser: mockGoogleUser)
print(mockUser.name) // prints "Mock User Name"
当然,您仍然可以使用“真实的” Google用户对象来初始化User
:
let realGoogleUser: GIDGoogleUser = ... // get a GIDGoogleUser after signing in
let realUser = User(googleUser: realGoogleUser)
print(realUser.name) // prints whatever the real GIDGoogleUser's name is