All Projects → migueleliasweb → go-github-mock

migueleliasweb / go-github-mock

Licence: MIT license
A library to aid unittesting code that uses Golang's Github SDK

Programming Languages

go
31211 projects - #10 most used programming language
shell
77523 projects

Projects that are alternatives of or similar to go-github-mock

Mockery
A mock code autogenerator for Golang
Stars: ✭ 3,138 (+4880.95%)
Mutual labels:  mock, mocking
Http Fake Backend
Build a fake backend by providing the content of JSON files or JavaScript objects through configurable routes.
Stars: ✭ 253 (+301.59%)
Mutual labels:  mock, mocking
Httpretty
Intercept HTTP requests at the Python socket level. Fakes the whole socket module
Stars: ✭ 1,930 (+2963.49%)
Mutual labels:  mock, mocking
Sinon Jest Cheatsheet
Some examples on how to achieve the same goal with either of both libraries: sinon and jest. Also some of those goals achievable only by one of these tools.
Stars: ✭ 226 (+258.73%)
Mutual labels:  mock, mocking
Mockiato
A strict, yet friendly mocking library for Rust 2018
Stars: ✭ 229 (+263.49%)
Mutual labels:  mock, mocking
Duckrails
Development tool to mock API endpoints quickly and easily (docker image available)
Stars: ✭ 1,690 (+2582.54%)
Mutual labels:  mock, mocking
Fake Xrm Easy
The testing framework for Dynamics CRM and Dynamics 365 which runs on an In-Memory context and deals with mocks or fakes for you
Stars: ✭ 216 (+242.86%)
Mutual labels:  mock, mocking
Nsubstitute
A friendly substitute for .NET mocking libraries.
Stars: ✭ 1,646 (+2512.7%)
Mutual labels:  mock, mocking
Axios Mock Adapter
Axios adapter that allows to easily mock requests
Stars: ✭ 2,832 (+4395.24%)
Mutual labels:  mock, mocking
Mocktopus
Mocking framework for Rust
Stars: ✭ 179 (+184.13%)
Mutual labels:  mock, mocking
Pester
Pester is the ubiquitous test and mock framework for PowerShell.
Stars: ✭ 2,620 (+4058.73%)
Mutual labels:  mock, mocking
Python Mocket
a socket mock framework - for all kinds of socket animals, web-clients included
Stars: ✭ 209 (+231.75%)
Mutual labels:  mock, mocking
Mockoon
Mockoon is the easiest and quickest way to run mock APIs locally. No remote deployment, no account required, open source.
Stars: ✭ 3,448 (+5373.02%)
Mutual labels:  mock, mocking
Faker
Provides fake data to your Android apps :)
Stars: ✭ 234 (+271.43%)
Mutual labels:  mock, mocking
Spy
Clojure/ClojureScript library for stubs, spies and mocks.
Stars: ✭ 131 (+107.94%)
Mutual labels:  mock, mocking
Mockito
Most popular Mocking framework for unit tests written in Java
Stars: ✭ 12,453 (+19666.67%)
Mutual labels:  mock, mocking
Really Need
Node require wrapper with options for cache busting, pre- and post-processing
Stars: ✭ 108 (+71.43%)
Mutual labels:  mock, mocking
Parrot
✨ Scenario-based HTTP mocking
Stars: ✭ 109 (+73.02%)
Mutual labels:  mock, mocking
Mocktail
A mock library for Dart inspired by mockito
Stars: ✭ 172 (+173.02%)
Mutual labels:  mock, mocking
Ts Auto Mock
Typescript transformer to unlock automatic mock creation for interfaces and classes
Stars: ✭ 204 (+223.81%)
Mutual labels:  mock, mocking

go-github-mock

Go Reference Go Report Card

A library to aid unittesting code that uses Golang's Github SDK

Installation

go get github.com/migueleliasweb/go-github-mock

Features

  • Create mocks for successive calls for the same endpoint
  • Pagination support
  • Mock error returns
  • High level abstraction helps writing readabe unittests (see mock.WithRequestMatch)
  • Lower level abstraction for advanced uses (see mock.WithRequestMatchHandler)

Breaking changes

  • v0.0.3 the API for the server options have beem simplified
  • v0.0.4 fixes to the gen script caused multiple url matches to change

Example

import "github.com/migueleliasweb/go-github-mock/src/mock"

Multiple requests

mockedHTTPClient := mock.NewMockedHTTPClient(
    mock.WithRequestMatch(
        mock.GetUsersByUsername,
        github.User{
            Name: github.String("foobar"),
        },
    ),
    mock.WithRequestMatch(
        mock.GetUsersOrgsByUsername,
        []github.Organization{
            {
                Name: github.String("foobar123thisorgwasmocked"),
            },
        },
    ),
    mock.WithRequestMatchHandler(
        mock.GetOrgsProjectsByOrg,
        http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
            w.Write(mock.MustMarshal([]github.Project{
                {
                    Name: github.String("mocked-proj-1"),
                },
                {
                    Name: github.String("mocked-proj-2"),
                },
            }))
        }),
    ),
)
c := github.NewClient(mockedHTTPClient)

ctx := context.Background()

user, _, userErr := c.Users.Get(ctx, "myuser")

// user.Name == "foobar"

orgs, _, orgsErr := c.Organizations.List(
    ctx,
    *(user.Name),
    nil,
)

// orgs[0].Name == "foobar123thisorgwasmocked"

projs, _, projsErr := c.Organizations.ListProjects(
    ctx,
    *orgs[0].Name,
    &github.ProjectListOptions{},
)

// projs[0].Name == "mocked-proj-1"
// projs[1].Name == "mocked-proj-2"

Returning empty results

mockedHTTPClient := NewMockedHTTPClient(
    WithRequestMatch(
        GetReposIssuesByOwnerByRepo,
        []github.Issue{
            {
                ID:    github.Int64(123),
                Title: github.String("Issue 1"),
            },
            {
                ID:    github.Int64(456),
                Title: github.String("Issue 2"),
            },
        },
        []github.Issue{},
    ),
)

c := github.NewClient(mockedHTTPClient)

ctx := context.Background()

issues1, _, repo1Err := c.Issues.ListByRepo(ctx, "owner1", "repo1", &github.IssueListByRepoOptions{})

// len(issues1) == 2
// repo1Err == nil

issues2, _, repo2Err := c.Issues.ListByRepo(ctx, "owner1", "repo2", &github.IssueListByRepoOptions{})

// len(issues2) == 0
// repo2Err == nil

Mocking errors from the API

mockedHTTPClient := mock.NewMockedHTTPClient(
    mock.WithRequestMatchHandler(
        mock.GetUsersByUsername,
        http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            mock.WriteError(
                w,
                http.StatusInternalServerError,
                "github went belly up or something",
            )
        }),
    ),
)
c := github.NewClient(mockedHTTPClient)

ctx := context.Background()

user, _, userErr := c.Users.Get(ctx, "someUser")

// user == nil

if userErr == nil {	
    if ghErr, ok := userErr.(*github.ErrorResponse); ok {
        fmt.Println(ghErr.Message) // == "github went belly up or something"
    }
}

Mocking with pagination

mockedHTTPClient := NewMockedHTTPClient(
    WithRequestMatchPages(
        GetOrgsReposByOrg,
        []github.Repository{
            {
                Name: github.String("repo-A-on-first-page"),
            },
            {
                Name: github.String("repo-B-on-first-page"),
            },
        },
        []github.Repository{
            {
                Name: github.String("repo-C-on-second-page"),
            },
            {
                Name: github.String("repo-D-on-second-page"),
            },
        },
    ),
)

c := github.NewClient(mockedHTTPClient)

ctx := context.Background()

opt := &github.RepositoryListByOrgOptions{
    ListOptions: github.ListOptions{
        // in fact, the perPage option is ignored my the mocks
        // but this would be present in production code
        PerPage: 2,
    },
}

var allRepos []*github.Repository

for {
    repos, resp, listErr := c.Repositories.ListByOrg(ctx, "foobar", opt)

    if listErr != nil {
        t.Errorf("error listing repositories: %s", listErr.Error())
    }

    // len(repos) == 2

    allRepos = append(allRepos, repos...)

    if resp.NextPage == 0 {
        break
    }

    opt.Page = resp.NextPage
}

// matches the mock definitions len(page[0]) + len(page[1])
// len(allRepos) == 4

Why

Some conversations got started on go-github#1800 since go-github didn't provide an interface that could be easily reimplemented for unittests. After lots of conversations from the folks from go-github and quite a few PR ideas later, this style of testing was deemed not suitable to be part of the core SDK as it's not a feature of the API itself. Nonetheless, the ability of writing unittests for code that uses the go-github package is critical.

A reuseable, and not overly verbose, way of writing the tests was reached after some more interactions (months down the line) and here we are.

Thanks

Thanks for all ideas and feedback from the folks in go-github.

License

This library is distributed under the MIT License found in LICENSE.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].