SwiftUI-在预览中模拟@EnvironmentObject数据

时间:2020-04-20 20:14:58

标签: swift mocking swiftui

我有此代码:

struct WelcomeView: View {
    @EnvironmentObject var userService: UserService
    var body: some View {
        Text(userService.user.username)
    }
}

struct WelcomeView_Previews: PreviewProvider {
    static var previews: some View {
        WelcomeView().environmentObject(UserService())
    }
}

我想要实现的所有UI组件都使用模拟数据。我需要以某种方式告诉我们,在预览中,我想将Text(userService.user.username)视为Text("Alex")。我该如何运作?我需要在哪里初始化user.username以及在何处放置此模拟。我只想将user对象用于所有视图。在这个示例中,我只是跳过了它们。

2 个答案:

答案 0 :(得分:3)

假设UserService使用依赖项注入已正确设计,则可以在生产代码中进行任何显式更改时将其用于以下方法

struct WelcomeView_Previews: PreviewProvider {
    static var previews: some View {
        let userService = UserService()
        userService.user = User(username: "Alex", email: "alex@test.com") // << any predefined set up here
        // any more parameters set up here

        return WelcomeView().environmentObject(userService)
    }
}

答案 1 :(得分:2)

您可以在服务级别或视图级别插入模拟数据。由于您将在多个视图中使用它,因此建议您向服务中添加模拟功能(如下面的第一个示例所示)。

我不知道您的UserService是什么样子,因此我为这些示例添加了基本的实现。

服务水平

import SwiftUI

struct User {
    var username: String
}

class UserService: ObservableObject {
    @Published var user: User = User(username: "Initial username")

    // If a mock user is provided to the UserService it will replace the initial user.
    init(mockUser: User? = nil) {
        if let user = mockUser {
            self.user = user
        }
    }
}

struct WelcomeView: View {
    @EnvironmentObject var userService: UserService

    var body: some View {
        Text(userService.user.username)
    }
}

struct WelcomeView_Previews: PreviewProvider {
    static var previews: some View {
        WelcomeView()
            .environmentObject(UserService(mockUser: User(username: "Test username")))
    }
}

查看级别

import SwiftUI

struct User {
    var username: String
}

class UserService: ObservableObject {
    @Published var user: User = User(username: "Initial username")
}

struct WelcomeView: View {
    @EnvironmentObject var userService: UserService

    // Optional mock user. Will replace the user from UserService if provided.
    var mockUser: User? = nil

    var body: some View {
        Text((mockUser != nil) ? mockUser!.username : userService.user.username)
    }
}

struct WelcomeView_Previews: PreviewProvider {
    static var previews: some View {
        WelcomeView(mockUser: User(username: "Test username"))
            .environmentObject(UserService())
    }
}