QML:单元测试中未调用信号

QML: Signal isn't being called in a unit test

我正在编写一个 C++ class ScriptProcess,旨在用于 QML,充当子进程的接口。所述子进程加载脚本,然后按需执行功能。当您调用函数时,结果(无论是值还是异常)通过信号异步返回。

import QtQuick 2.5
import QtTest 1.0
import dungeon 1.0

TestCase {
    id: test
    name: "ScriptProcessTest"

    property ScriptProcess session: null

    signal exceptionWhenLoadingCode(string type, int line, string message)

    SignalSpy {
        id: exceptionSpy
        target: test
        signalName: "exceptionWhenLoadingCode"
    }

    Component {
        id: process

        ScriptProcess {
            id: script

            onExceptionWhenLoadingCode: test.exceptionWhenLoadingCode(type, line, message)
        }
    }

    function startScript(scriptUrl) {
        var request = new XMLHttpRequest()
        request.open("GET", "data/%1.js".arg(scriptUrl), false)
        request.send(null)

        return process.createObject(test, {code: request.responseText})
    }

    function cleanup() {
        if (session) {
          session.stop()
        }

        delete session
        session = null
    }

    function test_syntaxErrorInGlobalContextIsReported() {
        var count = exceptionSpy.count
        session = startScript("syntax-error-in-global-context")

        compare(exceptionSpy.count, count + 1)
    }

    function test_errorThrownInGlobalContextIsReported() {
        var count = exceptionSpy.count
        session = startScript("error-in-global-context")

        compare(exceptionSpy.count, count + 1)
    }
}

简而言之,我执行以下操作:

  1. 对于每个测试,打开辅助进程并从文件加载脚本。这是通过实例化一个 Component 来完成的,脚本通过 ScriptProcess.code 属性.
  2. 运行 测试。
  3. 测试完成后,终止进程并删除管理它的对象。

我的问题是名为 exceptionSpySignalSpy 没有被触发; exceptionSpy.count 始终为零,我不知道为什么。 为什么会这样?我是在误用 ​​SignalSpy 还是 Component

XMLHttpRequest 是异步的,因此您应该将 startScript() 更改为类似以下内容:

function startScript(scriptUrl) {
    var object = process.createObject(test)

    var request = new XMLHttpRequest()
    request.onreadystatechange = function() {
        if (request.readyState === XMLHttpRequest.DONE)
            object.code = request.responseText
    }
    request.open("GET", "data/%1.js".arg(scriptUrl), false)
    request.send(null)

    return object
}

并且由于信号不会立即发出,您必须等待它,而不是在创建对象后立即比较计数:

function test_foo() {
    var count = exceptionSpy.count
    session = startScript("...")

    tryCompare(exceptionSpy, "count", count + 1)
}