Follow the Phoenix installation instructions and then start a new project with
mix phoenix.new my_blog. Once all the dependencies are installed and you’ve
created your database with mix ecto.create, we can get started.

In the setup block we are generating a conn to be used. Note that when Phoenix
1.1 is released this will be done automatically by MyBlog.ConnCase.

The second part of the tuple returned in the setup block is available as the
second argument to your test. We pattern match against it to make the conn
available to our test.

We are calling the ExMachina function called create_pair/3 that will
insert 2 posts. We could have used build_pair/3 if we didn’t need to save to
the database, but in this case we need the posts saved.

Next we make a request to our controller and then check that the response has
the titles of each of our blog posts.

The html_response helper makes sure that the response was successful (status
code 200) and returns the HTML body. Using =~ checks that whatever is on the
right hand side (post.title) is found somewhere in the string on the left hand
side (the HTML body).

Now let’s try to run the tests with mix test. You should get an error like
this:

Now let’s create our factory for generating test data. We’ll do this in
lib/my_blog/factory.ex. Be sure to make the extension .ex and not .exs or
it will not be compiled and you will get errors. See the ExMachina README for
the latest.

This is setting up a factory called :post that is built using the
MyBlog.Post struct. The body and author are static, but the title uses the
sequence/2 to ensure that the title is always unique. Whenever a post is built
or created n will be incremented by 1. The &("My Post #{&1}") syntax is a
shorthand for fn(n) -> "My Post #{n}" end. You can use whichever one you are
most comfortable with.

Let’s add our factory to MyBlog.ConnCase so that our factory functions are
available in all of our controller tests.

In test/support/conn_case.ex add import MyBlog.Factory in the using block.

usingdoquotedo# ...other code automatically generated by Phoenix when you start a projectimportMyBlog.Factoryendend

Let’s finish off the controller and make sure we are rendering our posts.

defmoduleMyBlog.PostControllerdouseMyBlog.Web,:controlleraliasMyBlog.Postdefindex(conn,_params)do# MyBlog.Repo is aliased for you when you `use MyBlog.Web, :controller`posts=Repo.all(Post)render(conn,"index.html",posts:posts)endend

We’re going to use another sequence so that when we build or create a :tag, the
name is always unique. When building a :post_tag we will build a post and a tag
by default. This can be overridden just like any other attribute. We’ll see how
to do that in a second.

This test will work, but the problem is that the test is brittle and not very
expressive. If someone needs to create a tagged post in another test they will
have to remember to do this. If you change how you create posts, you will then
need to change this in every test that uses it.

Instead let’s add a function to our factory in lib/my_blog/factory.ex to make
this more clear.

Now if you need to create a tagged post in another test, it is much easier to do
so. This is also nice because if we change how we tag posts we can just update
the tagged_with/2 function instead of changing every test.

Using regular functions with ExMachina can make your code easier to read, and
easier to change in the future.