Coder Social home page Coder Social logo

mock_me's Introduction

MockMe

MockMe is a simple mock server used to mock out your third party services in your tests. Unlike many mocking solutions, MockMe starts a real HTTP server and serves real static responses which may be toggled easily using the MockMe.set_response(:test, :result) function in your tests.

Under the hood this package uses Plug.Router to manage the routes and Plug.Cowboy for the HTTP server. The path in the routes can be any valid path accepted by Plug.Router. See the Plug.Router docs or examples for more information.

Installation

This package can be installed by adding mock_me to your list of dependencies in mix.exs:

def deps do
  [
    {:mock_me, "~> 0.1.0"}
  ]
end

The docs can be found at https://hexdocs.pm/mock_me.

Philosophy

Most applications today obtain data from external sources using TCP. Typically, when integrating with these sources you have a few options when writing tests:

  1. Not test the code which calls out to these services. Not an option in my opinion, but all too often this is the chosen path.
  2. Short circuit the code paths before reaching out to the external service using some type of function overwrite mechanism in your tests. While better than not testing, this path often leaves you with untested code paths which could become issues or throw errors later. It also leaves you in a place where your tests do not acurrately document your code.
  3. Use something like VCR which will make an initial request to the live third party service the first time and then playback that recorded response on subsequent requests. This is a valid strategy, but I've always found it cumbersome to setup and manage. I also like to know exactly what is being returned in requests.
  4. Use Liskov substitution to replace your API client interface with a mocked out module which mimics the behaviour of your adapter. While this is an excellent way to design your code, and a good idea to ensure your interface contracts, it falls short when doing integration tests because you're not actually testing the code that will be running in production.
  5. Set up your own mock server which will respond to real HTTP requests and thus test your entire code path just like it would perform in production.

Of all the options I prefer the last and it's what I do in all my Elixir projects. If you do it from scratch, it's only 2 files and takes very little effort. However, I got tired of setting it up in all my projects so I built an abstration with simple configuration that will build the server and run it for you in your tests.

This project is built based on my own personal use. I'm certain there are other use cases and options which you may want to build into it. If you would like to contribute, please head over to the GitHub Repo and request access to make pull requests. I hope you find this project as useful as I have.

Setup

The only things you need to do are:

  1. add {:mock_me, "~> 0.1.2", [only: [:test], runtime: false]} to your dependencies in mix.exs
  2. configure your code to point to the mock server url http://localhost:<port (9081)>
  3. configure your routes in your test/test_helper.exs file
  4. start the MockMe server in your /test/test_help.exs file
  5. use MockMe in your tests

Config

config/test.exs

config :mock_me, port: 9081

This is only used if you want to change the port the mock server listens to. The default port is 9081.

Dependencies

Add :mock_me to your project dependencies.

mix.exs



def deps do
  [
    {:mock_me, "~> 0.1.0"}
  ]
end

Initilization

test/test_helpers.ex



ExUnit.start()
MockMe.start()

routes = [
  %MockMe.Route{
    name: :swapi_people,
    path: "/swapi/people/:id",
    responses: [
      %MockMe.Response{
        flag: :success,
        body: MockMePhoenixExample.Test.Mocks.SWAPI.people(:success)
      },
      %MockMe.Response{flag: :not_found, body: "people-failure", status_code: 404}
    ]
  },
  %MockMe.Route{
    name: :swapi_starships,
    path: "/swapi/starships/:id",
    responses: [
      %MockMe.Response{
        flag: :success,
        body: MockMePhoenixExample.Test.Mocks.SWAPI.starships(:success)
      },
      %MockMe.Response{flag: :not_found, body: "starships-failure", status_code: 404}
    ]
  }
]

MockMe.add_routes(routes)
MockMe.start_server()

Use

test/mock_me_phoenix_example/services/starwars.exs

defmodule MockMePhoenixExample.Services.StarWarsTest do
  use ExUnit.Case
  alias MockMePhoenixExample.Services.StarWars

  # setup_all %{} do
  #   # re-initializes the test case state
  #   MockMe.reset_flags()
  # end

  test "people/1 returns success" do
    MockMe.set_response(:swapi_people, :success)
    assert {:ok, _} = StarWars.people(1)
  end

  test "people/1 returns not found" do
    MockMe.set_response(:swapi_people, :not_found)
    assert {:not_found, _} = StarWars.people(1)
  end

  test "starships/1 returns success" do
    MockMe.set_response(:swapi_starships, :success)
    assert {:ok, _} = StarWars.starships(1)
  end

  test "starships/1 returns not found" do
    MockMe.set_response(:swapi_starships, :not_found)
    assert {:not_found, _} = StarWars.starships(1)
  end
end

mock_me's People

Contributors

katehedgpeth avatar nbriar avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.