Examples of using eunit's 'with'?

The documentation for with says it looks like this:

{with, X::any(), [AbstractTestFun::((any()) -> any())]}

but meck uses it like this (simplified):

meck_test_() ->
{foreach, fun setup/0, fun teardown/1,
 [{with, [T]} || T <- [fun new_/1, fun unload_/1]]}.

These don’t agree…?

The meck usage expands to something like this:

{foreach, fun setup/0, fun teardown/1,
 [
  {with, [fun new_/1]},
  {with, [fun unload_/1]}
]}.

But I’ve also managed to (seemingly) get it to work as follows:

{foreach, fun setup/0, fun teardown/1, [
  {with, [fun new_/1, fun unload_/1]}
]}.

I’ve tried a couple of other variations, but I always end up with a “bad generator” error.

Are there any good examples of how to use with?

2 Likes

I found part of the confusion – the documentation’s a bit spread out. There’s a comment in eunit_data.erl which I find easier to read.

There are two ways to use with. Here’s the first one:

%% @type tests() =
%%          ...
%%          | {with, X::any(), [AbstractTestFunction]}

You use it like this:

%% {with, X::any(), [AbstractTestFunction]}
with_test_() ->
    {ok, Pid} = simple_server:start_link(),
    {with, Pid, [
        fun pass/1,
        fun fail/1
    ]}.

Here’s the second one (and the one that meck is using):

%% Instantiator = (R::any()) -> tests()
%%              | {with, [AbstractTestFunction]}

You can use it like this:

%% Instantiator = (R::any()) -> tests()
%%              | {with, [AbstractTestFunction]}
setup_with_test_() ->
    {setup, fun setup/0, fun cleanup/1,
        {with, [
            fun pass/1, fun fail/1
        ]}}.

foreach_with_test_() ->
    {foreach, fun setup/0, fun cleanup/1, [
        {with, [
            fun pass/1, fun fail/1
        ]}
    ]}.

Note that {setup, Setup, Cleanup, Instantiator} (doesn’t take a list) is different from {foreach, Setup, Cleanup, [Instantiator]} (takes a list).


Alternatively, you can do this, which doesn’t use with at all:

setup_result_test_() ->
    {setup, fun setup/0, fun cleanup/1, fun(Pid) ->
        [
            fun() -> pass(Pid) end,
            fun() -> fail(Pid) end,

            ?_test(pass(Pid)),
            ?_test(fail(Pid)),
        ]
    end}.
2 Likes