Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to verify that a view injects an environmentObject to one of its subviews #149

Closed
pobengtsson opened this issue Dec 13, 2021 · 4 comments · Fixed by #150
Closed

How to verify that a view injects an environmentObject to one of its subviews #149

pobengtsson opened this issue Dec 13, 2021 · 4 comments · Fixed by #150

Comments

@pobengtsson
Copy link
Contributor

pobengtsson commented Dec 13, 2021

(A solution proposal ready become a PR for this issue, if you would be willing to consider it)

I have a custom view that uses custom child views. The child views depends on an @EnvironmentObject.

struct ParentView: View {
   var body: some View {
       ChildView()
            .environmentObject(theObject) // the code I want to verify
   }
}

struct ChildView: View {
   @EnvironmentObject var anObject: TheObject
   var body: some View {
      EmptyView()
   }
}

class TheObject: ObservableObject {}

I want to test that the parent view injects the environment object as expected, but when I try:

       let expectation = XCTestExpectation()
       var sut = TestCustomView()
       sut.on(\.didAppear) { view in
          defer { expectation.fulfill() }
          _ = try view.find(ChildView.self).actualView().anObject
       }
       ViewHosting.host(view: sut.environmentObject(TheObject()))
       wait(for: [expectation], timeout: 1)

I get fatal error that anObject is not set on the child. As I understand other issues concerning EnvironmentObject (#88, #32, #62) this is not (yet?) supported.

So, then I thought, well maybe I can at least check that the parent view has the modifier set with the type of object that I expect, but I could not find any support for that. I found support for getting the modifier-injected-value when it was writable-key.

After some debugging/code broswing/reading, I found that there the code was quite prepared for what I wwas looking for and there was only a few funcs to be added to make it work. And, low and behold, it seems to work.

Would you be interesting in a PR (including tests) for this?
Or, would you recommend another way of verifying the behaviour concerning environmentObject?

pobengtsson added a commit to pobengtsson/ViewInspector that referenced this issue Dec 13, 2021
@nalexn
Copy link
Owner

nalexn commented Dec 13, 2021

Hey @pobengtsson ,

I see where the problem is. EnvironmentObject injection in the child views is working, that is if you inspected something inside the child view that reads from the Env object, it'd work (for example inspect value from Text(theObject.value) in the child)

That being said, when you request actualView(), it returns the view structure as-is, disconnected from the environment (thus the error when you access the env object on it).

I consider this a bug in the library, as the env object technically can be injected in the view before returning from actualView(). There is a func inject(environmentObject: AnyObject) that had to be called.

I'll work on a fix for the coming next version (or you can try fixing it if you want). Thanks for the report!

@nalexn
Copy link
Owner

nalexn commented Dec 13, 2021

As a separate note, there is no need to create expectation as the on function already does it for you (and calls fulfill at the end):

func testTT() throws {
    var sut = ParentView()
    let expectation = sut.on(\.didAppear) { view in
        _ = try view.find(ChildView.self).actualView().anObject
    }
    ViewHosting.host(view: sut.environmentObject(TheObject()))
    wait(for: [expectation], timeout: 1)
}

@pobengtsson
Copy link
Contributor Author

Thanks for the instant feedback.
Thats great news!! So I'll take a look and maybe, if I can understand it well enough and I can understand what the needed changes are, I'll attempt a few tests and a solution.

@pobengtsson
Copy link
Contributor Author

@nalexn your clues on what was needed made it easy to find and fix. Unless, I completely missunderstood.
I pushed it as PR for your review. #150

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants