Posted on Friday, 3rd October 2008 by charpi
People coming from object oriented programming often use mock
object in their unittest. The main question is do we need mock
when programming with erlang ? .
The answer could be we don’t need any mock library because it’s
already part of the language.
Let me explain a little more my vision of
The main purpose of the mock is to replace something
behavior and that you can control. Using this mock, your tests will
only focus on one class module and forget all about the
environment of the complicated thing.
Using good unittest practices in OOP, you’ll pass all needed object in
the constructor of your classes, so you’ll be able to use mock in your
unittests.
In Erlang, we can’t use this technique because we don’t have
constructors however we can write
- Erlang is a concurrent programming language so we might have to
test relationships between several processes. In order to test
processes one by one, we can just spawn a small process in our tests
and then pass its pid to the process under test. After that the
only thing to do it to implement the message passing between
processes. This technique is very close to the one used in OOP and
their constructors. - Erlang is a functional programming language. One of the most
interesting feature of FP is high order functions. It allows
you to pass functions to your functions. Usually, high order functions
are used to build generic algorithms but they can also be used to
modify function behavior.
Usingfun to mock some behavior, oblige you to write some
more tests:- Main function test with mock fun.
- Production fun.
- Real integration of the production fun in your application
Working on legacy code, it might be difficult to write tests. Of
course you can refactor to be able to use one of the previous case but
how to refactor without any tests ??. This observation make me realize
that
The first technique I used was dbg. Adding traces on function
call, you can ensure that an expected side effect happened.
Anyway, if you need to setup a complete environment
isn’t usable.
For those case a mock library could be useful. I have in mind
something that allow you to replace a module by another one.
There are the
-module(mock_test). -export([test /0]). test () -> lazy_way () , dynamic_way(), ok. lazy_way () -> "i'm the production code" = my_module: who(), mock: replace_module (my_module, my_mock_module), "I'm the mocked code" = my_module: who (), mock: uninstall (my_module), "i'm the production code" = my_module: who(), ok. dynamic_way () -> "i'm the production code" = my_module: who(), mock: start (), mock: add_module(my_module), mock: set_answer (my_module, who, "I'm the mocked code"), "I'm the mocked code" = my_module: who (), mock: set_answer (my_module, who, "Oops did it wrong"), "Oops did it wrong" = my_module: who (), [{my_module, who, []}, {my_module, who, []}] = mock: calls (), mock: uninstall (my_module), "i'm the production code" = my_module: who(), ok.
Tags: erlang, mock object
Posted in Uncategorized | Comments (4,015)