One approach I've considered is passing the module name as a parameter and in the unit test just mock the module with side-effects (example below). This worked, but maybe there's a better way to accomplish this that doesn't necessarily involve processes and message passing.
defmodule Repository dodef write_to_database(record) doIO.puts "Writing to DB"endenddefmodule Server dodef process_request(request, repository) dorequest|> request_to_record|> repository.write_to_databaseenddefp request_to_record(request) doend
end
Thanks in advance for sharing your thoughts.
--
You received this message because you are subscribed to the Google Groups "elixir-lang-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-ta...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Assuming we'd actually want to emulate this practice, I would expect to start with:* defprotocol Repository* supply the concrete implementation via: defimpl Repository, for: SomeRecordIt would be nice, assuming the above, to have something like:test "writes to repo" dorepo = defmock Repository, for: SomeRecord doassert write_to_database(r = SomeRecord[field1: "value"]) dois_valid = r.field2 |> String.contains? "est"{is_valid, "field2 incorrect, was #{inspect r.field2}"}endendSubjectUnderTest.method_to_test "value", "question"repo.verifyend
I don't know of anything like this proposed defmock for Elixir today. Does it exist? If not, is it workable considering protocol dispatch, maps, and record deprecations?
Isn't the reason to add the module as an argument to the function as you suggest to make it testable? I would suggest that having to explicitly supply the module as an argument increases coupling at the call site; I'd go so far as to say that the callee is now a leaky abstraction.
What I like about the handle_undefined_function mocking you described is the generality, but it seems to me that we're just trying to achieve late-binding in a few different ways. Ideally, there would be just one way that was equally useful in the application proper and its tests. I know there are perf and maintainability concerns, but it would be nice to be able to opt-in (or perhaps opt-out) of a dynamic dispatch regime.
José, when you say "pass the module" do you mean pass the module name?
Robert
--
You received this message because you are subscribed to the Google Groups "elixir-lang-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-ta...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Yes, exactly!
On Thursday, April 17, 2014, Robert Virding <rvir...@gmail.com> wrote:
José, when you say "pass the module" do you mean pass the module name?--
Robert
You received this message because you are subscribed to the Google Groups "elixir-lang-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-talk+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-ta...@googlegroups.com.
Is modules-as-values something that can be done today, i.e. without changing the VM?
I seem to recall it being something Joe played with in his Erlang2. ML-style functors would be a very powerful addition.
And then:defmodule Set dodef generate(name, module) dodefmodule name do@functor_arg moduledef empty() do[]enddef compare(a, b) do...@functor_arg.compare(a, b)...endendendend
Set.generate(StringSet, OrderedString)