Python - HowTo unittest i2c device wrapper class

573 views Asked by At

I have a python class that abstracts a dedicated device (power sensor) connected over i2c. I use the python-smbus module for the I2c access. Within that class, of course, I have methods (i.e. current_ma that returns the current value in milli ampere) using the smbus.SMBus() class.

import smbus

class PowerSensor(object):
    def __init__(self, bus, addr):
        self.__bus = smbus.SMBus(bus)
        self.__addr = addr

    def current_ma(self):
        data = self.__bus.read_i2c_block_data(self.__addr, 0x04)
        if data[0] >> 7 == 1:
            current = data[0] * 256 + data[1]
            if current & (1 << 15):
                current = current - (1 << 16)
        else:
            current = (data[0] << 8) | (data[1])
        return current / 10

To unittest the current_ma method I have to mock-up the smbus access. My first Idea was to patch the read_i2c_block_data method:

mock.patch('power_sensor.smbus.SMBus.read_i2c_block_data')

But if I do so while executing my test I got:

TypeError: can't set attributes of built-in/extension type 'smbus.SMBus'

I'm pretty sure, this is because smbus is a module written in C. So It's not patchable. I read the solution for that is subclassing the SMBus class. But this means I have to use these subclass in my PowerSensor class too, isn't it? That doesn't sound quite convenient. Is there a better way to solve that problem?

Thanks & Regards

0

There are 0 answers