简体   繁体   中英

SwiftUI - Mocking @EnvironmentObject data in preview

I have this code:

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())
    }
}

What I want to achieve that all my UI components use mock data. I need to tell somehow that in preview I would like to see Text(userService.user.username) as Text("Alex") for example. How can I make it work? Where I need to initialise my user.username and where to put this mock. I just want to use the user object for all my views. I just skipped them for this example.

Assuming the UserService has correctly designed using dependency injection, it can be used the following approach with any explicit changes in production code

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)
    }
}

You can either insert the mock data at the service level or at the view level. Since you'll be using this in multiple views, I'd recommend adding the mock capability to the service (as in the first example below).

I don't know what your UserService looks like so I've added a basic implementation to these examples.

Service level

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")))
    }
}

View level

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())
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM