Hi Forum,
My code uses hardware.millis() to keep track of the elapsed time.
I want to write an unit test of a modules that uses hardware.millis(). I am specially interested in testing my module behavior when hardware.millis() overflows and becomes negative without having to wait approx. 25 days.
Questions:
Is it possible to OVERRIDE hardware.millis() method ?
Perhaps is necessary to mock the whole hardware global table in order to mock just one method like hardware.millis() ? Are there other alternatives?
As far as I remember, you would need to mock the entire hardware table - well, the calls you use - in order to intercept that call. I remember this being done by a customer previously for the imp. calls but can’t find the code in github at this point.
No, I don’t think so. You need to make a new global table called hardware, and then implement all the hardware.XXX calls within that. I’m not the squirrel expert when it gets this deep, but @phil might be able to give an example of how you would call the original handlers from an override table.
Here’s one way to override millis() and still pass through all the other methods and member objects. It would be trickier if any of the methods had explicit parameters, and also obviously changes typeof(hardware), but might be enough for your use case.
class MockableHardware {
_hardware = null;
constructor(hardware) { _hardware = hardware; }
function millis() { return 123456; }
function _get(key) {
local v = _hardware[key];
return (typeof(v) == "function") ? function() { return v.call(_hardware); } : v;
}
};
hardware <- MockableHardware(hardware);
Some test code for the above:
server.log(hardware.getdeviceid());
server.log(hardware.lightlevel());
server.log(hardware.micros());
server.log(hardware.millis());
try {
server.log(hardware.vbat());
} catch(e) {
server.log("vbat not supported by "+imp.info().type);
}
server.log(hardware.voltage());
server.log(hardware.wakereason());
server.log(hardware.pin1); // imp001
server.log("configure" in hardware.pin1); // imp001
I think that’s working then. getdeviceid() is returning a sensible value and meta is the expected type for imp API objects like hardware itself and the GPIO pins. The configure method is visible on the passed-through pinK so those objects should all work correctly.
It’s just voltage() that will fail, because that method isn’t implemented for imp005.