Skip to content

Instantly share code, notes, and snippets.

@stwind
Last active December 20, 2015 09:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stwind/6109054 to your computer and use it in GitHub Desktop.
Save stwind/6109054 to your computer and use it in GitHub Desktop.
-module(ct_help).
-export([mock/2]).
-export([load_mocks/1]).
-export([unload_mocks/1]).
-include_lib("common_test/include/ct.hrl").
mock(Mocks, Config) ->
lists:foldl(fun do_mock/2, Config, Mocks).
load_mocks(Config) ->
{Mocks, Config1} = mocks(Config),
[moka:load(M) || M <- Mocks],
Config1.
unload_mocks(Config) ->
{Mocks, Config1} = mocks(Config),
[moka:stop(M) || M <- Mocks],
Config1.
%% ===================================================================
%% Private
%% ===================================================================
f(Fun) ->
{arity, Arity} = erlang:fun_info(Fun, arity),
f(Arity, Fun).
f(0, Fun) -> fun() -> {ok, Fun()} end;
f(1, Fun) -> fun(A) -> {ok, Fun(A)} end;
f(2, Fun) -> fun(A,B) -> {ok, Fun(A,B)} end;
f(3, Fun) -> fun(A,B,C) -> {ok, Fun(A,B,C)} end;
f(4, Fun) -> fun(A,B,C,D) -> {ok, Fun(A,B,C,D)} end;
f(5, Fun) -> fun(A,B,C,D,E) -> {ok, Fun(A,B,C,D,E)} end;
f(6, Fun) -> fun(A,B,C,D,E,F) -> {ok, Fun(A,B,C,D,E,F)} end;
f(7, Fun) -> fun(A,B,C,D,E,F,G) -> {ok, Fun(A,B,C,D,E,F,G)} end.
do_mock({_, []}, Config) ->
Config;
do_mock({Mod, [{Fun, Behavior} | Rest]}, Config) ->
{M, Config1} = get_mock(Mod, Config),
replace(M, Fun, Behavior),
do_mock({Mod, Rest}, Config1).
get_mock(Mod, Config) ->
{Mocks, Config1} = mocks(Config),
case dict:find(Mod, Mocks) of
{ok, M} ->
{M, Config1};
error ->
M = moka:start(Mod),
Mocks1 = dict:store(Mod, M, Mocks),
{M, lists:keyreplace(mocks, 1, Config1, {mocks, Mocks1})}
end.
mocks(Config) ->
case ?config(mocks, Config) of
undefined ->
Mocks = dict:new(),
{Mocks, [{mocks, Mocks} | Config]};
Mocks ->
{Mocks, Config}
end.
replace(M, {Mod, Fun}, Behavior) ->
moka:replace(M, Mod, Fun, f(Behavior));
replace(M, Fun, Behavior) ->
moka:replace(M, Fun, f(Behavior)).
-module(foo_note).
-export([find_note/2]).
find_note(User, Name) ->
case foo_db:find([{type, note}, {user, User}, {name, Name}]) of
{ok, Note} ->
{ok, Note};
Error ->
Error
end.
-module(foo_SUITE).
-include_lib("common_test/include/ct.hrl").
-compile(export_all).
%% ===================================================================
%% Setup
%% ===================================================================
suite() ->
[
{timetrap, {seconds, 20}},
{ct_hooks, []}
].
all() ->
[
find_note
].
groups() ->
[
].
init_per_suite(Config) ->
Config.
end_per_suite(_Config) ->
ok.
init_per_group(_Group, Config) ->
Config.
end_per_group(_Group, Config) ->
Config.
init_per_testcase(find_note, Config) ->
Config1 = ct_help:mock([
{foo_user, [
{{foo_db, find}, fun(Conds) ->
{ok, {user, proplists:get_value(email, Conds)}}
end}
]},
{foo_note, [
{{foo_db, find}, fun(_Conds) ->
{error, not_found}
end}
]}
], Config),
ct_help:load_mocks(Config1);
init_per_testcase(_TestCase, Config) ->
Config.
end_per_testcase(_TestCase, Config) ->
ct_help:unload_mocks(Config),
Config.
%% ===================================================================
%% Test cases
%% ===================================================================
find_note(_) ->
{ok, User} = foo_user:find_user(<<"piyo@hoge.io">>),
{error, not_found} = foo_note:find_note(User, <<"fuga">>).
-module(foo_user).
-export([find_user/1]).
find_user(Email) ->
case foo_db:find([{type, user}, {email, Email}]) of
{ok, User} ->
{ok, User};
Error ->
Error
end.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment