woohaaha

woohaaha

Testing models that cannot be created without long chain of dependancies. Tips?

Hi all,

How do you write your context tests (create_thingy(attrs)) when there are a lot of associations that need to be created first?

Here is a contrived example. Let’s says I have a Door model that I’d like to test the color, material, price, etc..

A Door cannot be created without having to first create a Wall
A Wall cannot be created without having to first create a House
A House cannot be created without having to first create a Blueprint
A Blueprint cannot be created without having to first create a Contract
A Contract cannot be created without having to first create a Client
A Client cannot be created without having to first create a Prospect
and on and on… :man_facepalming:

I have a method in my Building context that sort of looks like this:

  def create_door(attrs \\ %{}) do
    %Door{}
    |> Door.changeset(attrs)
    |> Repo.insert()
  end

Ideally in my test I’d like to write something like:

{:ok, door} = create_door(%{price: 1_234, material: "wood", color: "white"})
assert door.color == "white"

However I cannot create the Door without passing in a wall_id and since that field cannot be null I’d need to create a Wall. The creation process then has to go all the way up to … create_user. Surely I’ve missed something huge I can do that will still make me confident in the production code, but won’t make testing difficult.

Any tips or suggestions are greatly appreciated.

First Post!

Mpanarin

Mpanarin

I am not very familiar with the approach in phoenix specifically, as I am pretty new to elixir. But this situation is very common in any other language.

I come from python world where this can be generally mitigated by 2 approaches:

  1. Data migrations. You basically create json or similar files with data, which you add to your test database before running the tests. I don’t really like this, as this is fairly fragile in my opinion
  2. You create factory classes (or methods|functions, etc.) that generate required objects with required parameters. So if you need a wall for a door your factory function will either get a wall as an argument of create a new one inside it. If to create a wall you need a house, it will create it inside its factory function, etc.

With second approach you will have to do a huge effort of creating this factories if your codebase is fairly big already. But they are easier to maintain as well as way more flexible for your tests )

Where Next?

Popular in Questions Top

chokchit
** (DBConnection.ConnectionError) connection not available and request was dropped from queue after 2733ms. You can configure how long re...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
Darmani72
If I have a post route which an argument: post /my_post_route/:my_param1, MyController.my_post_handler How would get the post params ...
New
JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
PeterCarter
There are pre-rolled solutions for other frameworks that do work. However, Phoenix does not seem to have these. Have people had good expe...
New

Other popular topics Top

chrismccord
As promised, the first release candidate of Phoenix 1.3.0 is out! This release focuses on code generators with improved project structure...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
josevalim
Hi everyone, One of the features added to Elixir early on to help integration with Erlang code was the idea of overridable function defi...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" => #BSON.ObjectId<58eb1a7a9ad169198c3dXXXX>, "email" => ...
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New
sergio
Kind of like when jquery came out, it was super necessary. Existing drag and drop libraries have a bunch of baggage to support old browse...
New

Latest on Elixir Forum

We're in Beta

About us Mission Statement