Mock Python-On-Whales

Question:

With a Pyhton script I want to determine, if a docker container is running. For this, I use python-on-whales. Something this way:

check_container.py

from python_on_whales import docker


class Container:
    def __init__(self, name):
        self.name = name

    def is_running(self):
        container_found = self.search_container()

        if container_found:
            for container in self.get_container_state():
                if container.state.status == "running":
                    return True
                else:
                    return False
        else:
            return False

    def search_container(self):
        return docker.ps(all, filters={"name": self.name})

    def get_container_state(self):
        return docker.ps(all, filters={"name": self.name})

Now, I want to test this in an unit test.

I tried different ways, but I didn’t found a correct way. Mostly I got an error "Object is not iterable" or an assertion error (None instead True)

This is an example… one of may. 😉
test_check_container.py

from unittest import TestCase, mock
from unittest.mock import patch

from src.check_container import Container


class Test(TestCase):

    @patch("src.check_container.Container.search_container")
    @patch("src.check_container.Container.get_container_state")
    def test_check_container(self, mock_container_state, mock_container):

        mock_container.return_value = mock.Mock([{"id": '123456789', "name": 'busybox'}])
        mock_container_state.return_value = mock.MagicMock([{"status": "running"}])
        container = Container("busybox")
        container_running = container.is_running()
        assert container_running is True

Anyone an idea, how to mock the "docker.ps" calls and to solve my issue.

Asked By: Qaldak

||

Answers:

have thought too far. With the following approach I was able to optimize the code and also make the test a bit easier.

check_container.py

from python_on_whales import docker


class Container:
    def __init__(self, name):
        self.name = name

    def is_running(self):
        if docker.ps(all=True, filters={"name": self.name, "status": "running"}):
            return True
        else:
            return False

test_check_container.py

from unittest import TestCase
from unittest.mock import patch

from python_on_whales import docker

from src.check_container import Container


class TestDockerContainerRunning(TestCase):

    @patch("src.check_container.docker.ps", return_value=True)
    def test_container_running_mock(self, mock_container_state):
        assert Container("Foo").is_running() is True

With this few line of codes it’s possible to check if an Docker container is running.

Another way is to run a docker container for the test and remove it after:

def test_container_running(self):
    with docker.run("busybox", ["sleep", "infinity"], detach=True, remove=True, name="busybox") as c:
        assert Container("busybox").is_running() is True
Answered By: Qaldak