I got QML tests working for me without compiling in any C++ code.
In my case, I have a C++ object controller with a property called left_motor, which is another object, and that has a property speed.
Note that speed is readable, but not writable. Any updates will happen through slots. In QML that looks like this: controller.left_motor.onGuiSpeedChanged(speed)
I was able to mock this in QML using Item components, properties, and some javascript.
Item { // mock of controller
id: controller
property alias left_motor: left_motor
Item {
id: left_motor
property int speed: 0
function onGuiSpeedChanged(arg) {
speed = arg
}
}
}
property alias controller: controller
Now calls to controller.left_motor.onGuiSpeedChanged(speed) resolve like before, but connect into the mock function. I can even read back the speed property to know that the call happened.
Here is my test function (the code I'm testing is part of page1):
function test_set_speed() {
console.log("controller.left_motor.speed: " + controller.left_motor.speed)
var got = page1.set_left_speed(250)
compare(got, 250, "set_left_speed() return incorrect")
console.log("controller.left_motor.speed: " + controller.left_motor.speed)
}
Note that it's important to use slots instead of writable properties. The call to a slot looks just like a function call and can be mocked as such. I could not figure out a way to mock out a property write.
I had started out trying writable properties because that was the first thing in the documentation on binding C++ and QML. It connects QML and C++ as expected, but can't be mocked out for testing.