Closed janpieper closed 6 years ago
Hi, @janpieper ! Sorry for the late response! I will investigate soon.
Ok, @janpieper ! As I understand your goal is to implement the function:
def mock_example(name, retval) do
allow(Example).to accept(:hello, fn(name) -> retval end)
end
So you can mock :hello function with any pair of input / output Correct me if I'm wrong.
So I have at least two solutions for. First one works if you have a predefined set of input / outputs. You need just define dictionary (Map) with input / output values.
context "simple greetings" do
def ret_value_map do
%{"John" => "Hi, John", "Jane" => "Hi, Jane"}
end
def mock_example(name, retvalue) do
allow(Example).to accept(:hello, fn(name) -> Map.get(ret_value_map, name) end)
end
before do
mock_example("John", "Hi, John")
mock_example("Jane", "Hi, Jane")
end
it "greets John and Jane" do
expect(Example.hello("John")).to eq("Hi, John")
expect(Example.hello("Jane")).to eq("Hi, Jane")
end
end
If you don't know all the values, you can fill in the dictionary on the flight using Agent:
def mock_example(name, retvalue) do
put_to_agent(name, retvalue)
allow(Example).to accept(:hello, fn(name) -> get_from_agent(name) end)
end
I tried to use
:merge_expects
, which is an option thatmeck
provides. It can be used to define different functions to be executed if the arguments matches:The option
:merge_expects
will be passed to:meck.new/2
, but ESpec than calls:meck.expect/3
instead of:meck.expect/4
. Okay, ESpec doesn't know the arguments to pass them to:meck.expect/4
.I know that this can also be achieved by using pattern matching in the anonymous function:
But in my case, the arguments are dynamic.
Is there a way to achieve this with ESpec? Maybe with some meta programming voodoo or using a macro?