openSUSE:WebYaST Testing/D-Bus
Writing tests involving D-Bus
Following the Don't access the system conventions, here's how to simulate D-Bus calls when writing WebYaST tests.
[ Reference: Riding the D-Bus with Ruby ]
A short reminder of D-Bus 'speak'
Terms you need to know: Bus, Service, Object, Interface, Proxy
At its core, D-Bus offers 'remote procedure calls' in an object-oriented way.
A Service has Objects implementing Interfaces (set of functions).
Services are identified by dotted notation, i.e. "org.freedesktop.Hal"
Interfaces also have dotted notation, i.e. "org.freedesktop.Hal.Device.Storage.Removable"
Objects are identified by slashed notation, i.e. "/org/freedesktop/Hal/devices/storage_model_DVDRW_LH_20A1S"
Services are available globally (through the System bus) or locally (Session bus)
Since objects live 'on the other side' of D-Bus, you need to transfer a function call through D-Bus to the remote object.
This is greatly simplified by Proxy objects. A proxy is an object living on 'your' side of the D-Bus pretending to be the real thing. Internally, it is sending all function calls via D-Bus to the remote object and receives results back.
Mocking D-Bus
Most of the mocking details are available in the DBusStub Ruby class, part of the webyast-base-ws package
Your Ruby test case should have this line to import the DBusStub class
require File.expand_path( File.join("test","dbus_stub"), RailsParent.parent )
Now create a DBusStub instance with
dbus = DBusStub.new :system, "dbus.service.spec"
The first parameter can be :system for a service on the D-Bus System bus or :session for the Session bus
Next we create a proxy. The proxy is a local instance of a remote (D-Bus) object, pretending to be the real thing.
proxy = dbus.proxy "/path/to/service"
Service functions are offered through an interface, created by
interface = dbus.interface proxy, "dbus.service.spec.iface"
Since proxy and interface creation usually comes together, the above two calls can be combined in one as:
proxy,interface = dbus.proxy "/path/to/service", "dbus.service.spec.iface"
Now you can use normal Mocha calls to mock the interface functions, i.e.
interface.stubs(:Function).returns(true)