1

I'm not sure if static vs. dynamic mock is the terminology used to describe this comparison, but I got this terminology from types of mocking static vs dynamic and Hand-rolled mocks made easy. To summarize, a dynamic mock is a proxy generated on the fly, whereas a static mock is pre-implemented. For a Python example given this abstract Repository, Value domain object and example DatabaseRepository implemention:

class Value:
    ...

class Repository(ABC):
    @abstractmethod
    def read_value(value_id: str) -> Value:
        pass

class DatabaseRepository(Repository):
    def __init__(self):
        self.database_client = ...

    def read_value(value_id: str) -> Value:
        # Use `self.database_client` and `value_id` to fetch a parsable `Value`.
        ...

A static mock would look like:

from abc import ABC, abstractmethod

class MockRepository(Repository):
    def read_value(_: str) -> Value:
        return Value(...)  # Ignores `value_id` and returns predefined `Value` for mocking purpose.

static_mock = MockRepository()

A dynamic mock would look like:

from unittest.mock import Mock

dynamic_mock = Mock(spec=Repository)
dynamic_mock.read_value.return_value = Value(...)

In the code bases I've worked with, I've rarely seen the static mock. Yet the static mock seems to come with numerous benefits, a major one being compile-time safely for constructing the mock object in a statically typed language (or in Python, safety that can enforced by a type checker like mypy).

The only benefit to dynamic mocks seems to be the conciseness (also mentioned by the two links), and while this is a valid benefit, is there anything I'm missing in regards to what a dynamic mock can do exclusively or more naturally compared to a static mock? Does design of a particular language (like statically typed vs. dynamically typed) tilt this comparison scale?

1 Answer 1

2

What you have here is a stub. Stubs are used to inject values into other objects. These values can be used to take the execution down different logical paths in the function under test. Return true, return false, throw exception.

Creating stubs dynamically (considered configurable stubs) just keeps the code base clean and reduces the need to manage large amounts of helper classes. Hard-coded stubs are custom built for one test, so you can imagine how that would go with a code base with 1000 of tests. Soon as the test suite gets bigger the management of hard coded stubs gets problematic.

Mocks are different. They remember how they were used and that can be verified as part of the test; i.e. the SaveToDatabase() method was called three times.

There is a fantastic book called xUnit Test Patterns that contains everything you need to know about this topic. It's really good and shouldn't be too difficult to find.

2
  • So dynamic_mock is actually a configurable stub right now even though it's instantiated as Mock, but if I asserted that it/one of its methods was used X number of times then it would be considered a mock? Sep 2, 2020 at 15:53
  • 1
    Yes. Here is a great article from Martin Fowler, the link will take you to specific definitions but the whole article is interesting... the frameworks blur the definitions, probably for simplicity... martinfowler.com/articles/…
    – null
    Sep 2, 2020 at 18:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.