Open cmorse opened 4 years ago
Are you saying that the issue is that zwave
class is not up to date? That's very likely the case. Is this what you're fixing in your #37 ?
Or are you asking how to mock the code in question?
Or both? :)
This is separate from what's being fixed in #37. I'm asking how to mock the code in question. I tried to do it myself, but I am not good enough with Groovy.
Okay, so I think test should be looking something like this:
def "Basic validation"() {
setup:
VersionGet versionGet = Mock{
_*format() >> "Not sure what's supposed to be returned"
}
VersionV1 versionv1 = Mock{
_*versionGet() >> versionGet
}
Zwave zwave = Mock{
_*getVersionV1() >> versionv1
}
DeviceExecutor api = Mock{
_*getZwave() >> zwave
}
expect:
def script = sandbox.run(api: api)
script.updated()
}
The problem with this is that getZwave()
of DeviceExecutor
returns me.biocomp.hubitat_ci.api.device_api.zwave.Zwave
trait which is currently empty.
You'll need to update it to match the dump that you've made, add VersionV1
and VersionGet
mocks too, and then the example should work.
Sorry about that, as you have noticed, my device implementation is far from being complete. Thanks for helping me out with it. I might find time adding it later, but not sure when I have enough free time.
Thanks for the help.
I'm still having some issues getting this working.
I implemented Zwave and VersionV1 as follows:
package me.biocomp.hubitat_ci.api.device_api.zwave
trait Zwave {
abstract VersionV1 getVersionV1()
}
package me.biocomp.hubitat_ci.api.device_api.zwave.commandclasses
import me.biocomp.hubitat_ci.api.device_api.zwave.commands.versionv1.VersionGet
trait VersionV1 {
abstract VersionGet versionGet()
}
But, this doesn't work. I get a Cannot invoke method format() on null object
. A breakpoint placed in the Mock override of versionGet is never called.
But, if I rename the versionGet
function to versionGet2
, it starts working. My only idea for why is that Groovy thinks that versionGet
is a getter for a property called version
? If that is the case, I am not sure how to fix it.
Seems like some kind of an issue with Spock framework and versionGet
variable name matching method name.
I renamed it to versionGetMock
, and now it seems to be working for me (after updating Zwave
, Version1
and VersionGet
classes with your changes).
def "Smoke test for a few zwave properties"()
{
setup:
VersionGet versionGetMock = Mock{
_*format() >> "Not sure what's supposed to be returned"
}
VersionV1 versionv1 = Mock{
_*versionGet() >> versionGetMock
}
Zwave zwave = Mock{
_*getVersionV1() >> versionv1
}
DeviceExecutor api = Mock{
_*getZwave() >> zwave
}
def script = new HubitatDeviceSandbox("""
def installed() {}
def updated() {
def cmds = []
assert zwave != null
assert zwave.versionV1 != null
assert zwave.versionV1.versionGet() != null
assert zwave.versionV1.versionGet().format() == "Not sure what's supposed to be returned"
true
}
""").run(validationFlags: [Flags.DontValidateMetadata, Flags.DontRequireParseMethodInDevice], api: api)
expect:
script.updated()
}
That worked! Thanks! Are there any other options for doing this? Doing it this way gets rather tedious when you have code that uses a lot of zwave commands.
I think the answer is always "it depends" :) For example, it'll depend on what you want these methods and properties of zwave objects to return. And how you defined zwave classes you're mocking (which we should definitely add to hubitat_ci).
So maybe if you show me a code sample that you'd want tested (with all the complexity you're talking about), I can try to advise something specific.
I'm not sure there's a way for me to mock all of these zwave classes in hubitat_ci in a way that is useful for users, and not too complicated to implement. Or maybe instead of traits, we can define zwave classes to be real classes, and return some default values from their methods, this way you would not need to override too many methods/properties.
But in general, it's probably going to be something boring along these lines:
I've been trying to get commands like those inside of
updated()
in the example below to work. It always fails on thezwave.versionV1.versionGet()
with a "Cannot get property 'versionV1' on null object". I tried mockingDeviceExecutor.getZwave()
, but I just got casting exceptions. Based on the method dumps ofhubitat.zwave.Zwave
andhubitat.zwave.commandclasses.VersionV1
, I think theZwave
class may need to be expanded.here is a dump of hubitat.zwave.Zwave
and a dump of hubitat.zwave.commandclasses.VersionV1