Should i test using inner(private) logic?

I have a question about a good way to test pure functional classes. For example i have a module which holds a list of some entities in its struct. And it has two public functions: 1. Adding an entity and 2. get some information based on the list. Both of this functions are non trivial and, for example, depends on additional parameters. It’s not a good idea to test them together, since there are many different variations when they are intersect. The question is: How should I test them separately?
I can see two variants:

  1. Test them by using knowlege of inner implementation. I have to check on current implementation(structs, lists etc), and if it changes, all my tests will crash.
  2. Add a public function to API(for example in this case - list of entities), which will be used only by tests. If i do so, i could rely on it without inner knowlege. But is it good to have an API only for tests? It could be very confusing when other people read the module code and see no difference between that 3 methods. Comments may help, but anyway.

Am i missing something?

Sounds like the two functions have a lot of responsibilities (maybe too many) or they are the kind of “high-level entry point” ones.

I think there are a few options:

  • Make the data structure part of the API: for example Plug.Conn has public and “private” fields,
  • Add public accessors that will guard you from leaking implementation details: for example Phoenix.Controller.current_path/1,
  • Expose lower-lever building blocks, like OptionParser.next/2, and test those,
  • Redesign your code; maybe it’s possible to split the main function into smaller ones, e.g.: replace foo_bar(arg, opts) into foo_bar_case_1(arg) and foo_bar_case_2(arg)
1 Like

Thanks, i thought about bad/unappropriate design too. But it’s less obvious how to change :slight_smile: Thanks again

Definitely break apart those functions into smaller ones! It will help you a lot afterwards when you decide what and how much to test.

If you are having trouble with that and if the code is not a trade secret, feel free to ask the forum for advice. I personally love refactoring projects and making them simpler to evolve. I would help you with such an effort.

2 Likes

Thanks! I appriciate it, for now i’ve solve the problem, but i’ll ask in future if i need.