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

Faking out properties is a bit of a handful. #7

Open
younata opened this issue Mar 31, 2024 · 0 comments
Open

Faking out properties is a bit of a handful. #7

younata opened this issue Mar 31, 2024 · 0 comments
Milestone

Comments

@younata
Copy link
Member

younata commented Mar 31, 2024

If you try to apply a spy to a property, you're gonna have a bad time.

Read-only properties are at least not terrible, because they behave like standard functions.

final class FakeThing: Thing {
    var propertySpy = Spy<Void, Int>(1337)
    var property: Int { propertyFake() }
}

However, settable properties are just a terrible user experience. As of this issue, the only options are to either have the fake update spy's stub, or create 2 spies for the single property.

final class FakeThing: Thing {
    var updatingSpy = Spy<Void, Int>(1337)
    var updating: Int {
        get { propertyFake() }
        set { propertyFake.stub(newValue) }
    }

    var settableReadSpy = Spy<Void, Int>(1234)
    var settableWriteSpy = Spy<Int, Void>()
    var settable: Int {
        get { settableReadSpy() }
        set { settableWriteSpy(newValue) }
    }
}

Either one is not great. Spy.stub(_:) is only supposed to be called in a test, not in the implementation of a Fake. However, re-stubbing the spy in the fake does make the Fake behave a little more "real" - I would expect SomeRandomValue.property to return the same value I just set, which this single-spy approach does handle nicely. Furthermore, the double-spy approach is just an unwieldy mouthful, even if it is more able to catch assignments.

So, I think a PropertySpy would be an excellent thing to create, which essentially is 2 spies, for tracking reads as well as writes, with calls to the write updating the stub of the read (and an option to disable that behavior).

Additionally, setting all this up is a lot of boilerplate that you shouldn't have to engage in. Thankfully, swift offers ways around this, such as property wrappers and attached macros. Either one should work, with property wrappers being significantly easier to maintain.

@younata younata added this to the 1.0 milestone Apr 24, 2024
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

No branches or pull requests

1 participant