Skip to content

Mocking autogenerated files for unit tests? #105

@GustavLindberg99

Description

@GustavLindberg99

We would like to unit test the functionality of our dbus server by calling the methods directly without setting up an actual dbus server. For example our code for unit testing the calculator example would look something like this:

#include <gtest/gtest.h>
#include "calculator-server.hpp"

TEST(CalculatorTest, TestMultiply){
  Calculator calculator;
  EXPECT_EQ(calculator.multiply(2, 3), 6);
  EXPECT_EQ(calculator.lastResult(), 6);
  calculator.clear();
  EXPECT_EQ(calculator.lastResult(), 0);
}

The problem is that the Calculator class inherits from sdbusplus::server::object_t<sdbusplus::server::net::poettering::Calculator> which sets up an actual dbus server and requires a sdbusplus::bus_t object in the constructor. We would like to test its functionality without setting up a dbus server in the unit tests.

Our current solution is to manually mock the autogenerated and sdbusplus classes like this:

mocks.hpp

namespace sdbusplus {
  /**
   * Dummy placeholder for sdbusplus::bus_t, needed since the interface classes need to take a bus
   * as a constructor parameter.
   */
  class bus_t {};

  namespace server {
    /**
     * Mock for sdbusplus::server::object_t which defines the constructor called in the subclasses.
     */
    template <typename T>
    class object_t : public T {
    public:
      object_t(bus_t& bus, const char* objectPath) {}
    };
  }
}

namespace sdbusplus::server::net::poettering {
  /**
   * Mock of the autogenerated superclass for Calculator, defining virtual methods that can be inherited from.
   */
  class Calculator {
  public:
    virtual ~Calculator() = default;
    virtual int64_t multiply(int64_t x, int64_t y) = 0;
    virtual int64_t divide(int64_t x, int64_t y) = 0;
    virtual void clear() = 0;
    //TODO: Mock functionality for properties
  };
}

calculator-server.hpp

#ifdef UNIT_TEST
#include "mocks.hpp"
#else
#include <net/poettering/Calculator/server.hpp>
#include <sdbusplus/server.hpp>
#endif

using Calculator_inherit =
    sdbusplus::server::object_t<sdbusplus::server::net::poettering::Calculator>;

/** Example implementation of net.poettering.Calculator */
struct Calculator : Calculator_inherit {
    //Same implementation as in https://github.com/openbmc/sdbusplus/blob/master/example/calculator-server.cpp
};

The problem with this is that writing the mocked classes manually is tedious and not very maintainable, especially for the properties. It would be nice if there were a tool to autogenerate the mocked classes alongside the real classes.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions