Use more real DSL objects in the SWT specs (instead of stubs)
The idea would be to use the real DSL objects more in the SWT specs. @jasonrclark came up with the idea in #471 and as I'm fighting my way through rewriting specs right now I grow increasingly fond of the idea. E.g. I just made a stub with 13 stubbed methods and it still is a null object...
I know we ideally want to stub out what is not the object under test however:
- the stubbing gets to be an increasing pain every time features are added to the DSL, especially when they are added to all DSL objects (as when updating the Dimensions class) - as those things have to be stubbed EVERYWHERE then
- by their nature the backend is tightly coupled to the DSL object as it represents the DSL object and we removed the duplication between those two, e.g. it needs almost all DSL methods all the time
- DSL methods and objects should sufficiently be tested in the DSL layer testing phase so that they should not result in unexpected test failures on the backend side (DSL tests are run first with
rake spec)
One problem is that when creating a new DSL object instance it already creates its own backend object, so passing this DSl object to another backend/SWT object as the DSL object is not quite good. However we could just create the DSL object and then set the subject to dsl.gui
What do you think? Any input highly appreciated!
Tobi
Another thing that's hard to do without the DSL objects in the SWT objects: Test changes. We want to keep all the data in the DSL e.g. if we want to test that an attribute changes and some updates happen accordingly that is no obvious to do with the current specs. E.g. we have to change a double
A thought that occurred to me related to the DSL's creating their own backend objects--is there a way that we could stub out calls like this that the DSL makes:
@gui = Shoes.configuration.backend_for(self, @parent.gui, blk)
... to instead return the subject of the current Shoes::Swt test that's underway? Or maybe the other way around--subject could be defined to return, and as necessary for test setup modify, the backend element the DSL created itself?
Haven't tried any of these out yet, but wanted to jot down the thoughts before I lost them.
Personally I think that the following might be enough and the easiest:
let(:dsl) {DSLObject.new ...}
subject {dsl.gui}
Stubbing is a good idea, but we can not return the subject under test because the subject needs the dsl to be instantiated and as the instantiation of the backend representation happens in DSL#initialize we don't have the object yet... kind of a hen <--> egg problem or am I missing something?
jotting thoughts down is good almost all of the time - that's why I create so many issues even if they are discussions like this one =)
Thanks for your input!
I agree with @PragTob's setup suggestion (really, this is the same as @jasonrclark's 2nd proposal, only in 2 lines). The other thing to consider is converting mocks to verifying mocks where we don't use real objects. That will at least catch the scenario where we stub methods that don't exist (which also bit me recently).
big :+1: on verifying stubs/mocks whatever :)