https://github.com/bytedance/mockey

a simple and easy-to-use golang mock library

https://github.com/bytedance/mockey

Science Score: 13.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
  • DOI references
  • Academic publication links
  • Committers with academic emails
  • Institutional organization owner
  • JOSS paper metadata
  • Scientific vocabulary similarity
    Low similarity (10.5%) to scientific vocabulary

Keywords

golang mock test testing
Last synced: 5 months ago · JSON representation

Repository

a simple and easy-to-use golang mock library

Basic Info
  • Host: GitHub
  • Owner: bytedance
  • License: apache-2.0
  • Language: Go
  • Default Branch: main
  • Homepage:
  • Size: 147 KB
Statistics
  • Stars: 806
  • Watchers: 5
  • Forks: 33
  • Open Issues: 5
  • Releases: 22
Topics
golang mock test testing
Created over 3 years ago · Last pushed about 1 year ago
Metadata Files
Readme Contributing License Code of conduct

README.md

Mockey

English | 中文

Mockey is a simple and easy-to-use golang mock library, which can quickly and conveniently mock functions and variables. At present, it is widely used in the unit test writing of ByteDance services (7k+ repos) and is actively maintained. In essence it rewrites function instructions at runtime similarly to gomonkey.

Mockey makes it easy to replace functions, methods and variables with mocks reducing the need to specify all dependencies as interfaces.

Features

  • Mock functions and methods
    • Basic
      • Common / variant parameter function
      • Common / variant parameter method (value or pointer receiver)
      • Nested structure method
      • Fixed value or dynamic mocking (via custom defined hook functions)
      • Export method of private type (under different packages)
      • Conditional mocking (via custom defined hook functions)
    • Advanced
      • Execute the original function after mocking (decorator pattern)
      • Goroutine conditional filtering (inclusion, exclusion, targeting)
      • Incrementally change mock behavior - sequence support
      • Get the execution times of target function
      • Get the execution times of mock function
  • Mock variable
    • Common variable
    • Function variable

Requirements

  1. Mockey requires inlining and compilation optimization to be disabled during compilation or it won't run. See the FAQs for details.
  2. It is strongly recommended to use it together with the Convey library (module dependency)

Install

go get github.com/bytedance/mockey@latest

Quick Guide

```go import ( "fmt" "testing"

. "github.com/bytedance/mockey"
. "github.com/smartystreets/goconvey/convey"

)

// Simple function func Foo(in string) string { return in }

// Function method (value receiver) type A struct{} func (a A) Foo(in string) string { return in }

// Function method (pointer receiver) type B struct{} func (b *B) Foo(in string) string { return in }

// Value var Bar = 0

func TestMockXXX(t *testing.T) {

PatchConvey("Function mocking", t, func() {
    Mock(Foo).Return("c").Build()          // mock function
    So(Foo("anything"), ShouldEqual, "c")  // assert `Foo` is mocked
})

PatchConvey("Method mocking (value receiver)", t, func() { Mock(A.Foo).Return("c").Build() // mock method So(new(A).Foo("anything"), ShouldEqual, "c") // assert A.Foo is mocked })

PatchConvey("Method mocking (pointer receiver)", t, func() { Mock((B).Foo).Return("c").Build() // mock method b := &B{} So(b.Foo("anything"), ShouldEqual, "c") // assert `B.Foo` is mocked })

PatchConvey("Variable mocking", t, func() { MockValue(&Bar).To(1) // mock variable So(Bar, ShouldEqual, 1) // assert Bar is mocked })

// the mocks are released automatically outside PatchConvey fmt.Println(Foo("a")) // a fmt.Println(new(A).Foo("b")) // b fmt.Println(Bar) // 0 } ```

Compatibility

OS Support

  • Mac OS(Darwin)
  • Linux
  • Windows ### Arch Support
  • AMD64
  • ARM64 (mac/linux only) ### Version Support
  • Go 1.13+

Advanced features

Conditional mocking

```go PatchConvey("conditional mocking", t , func() { mock := Mock((*B).Fun). When(func(in string) bool { return len(in) > 10 }) // Same parameters as the mocked function parameter. The args are used to determine whether to execute the mock or not Return("MOCKED!"). Build()

// OR mock := Mock((*B).Fun). When(func(b *B, in string) bool { return len(in) > 10 }) // optionally the class reference can be passed as the first parameter Return("MOCKED!"). Build()

// we initialise dep := &B{}

// long string -> mocked So(dep.Fun("something long enough"), ShouldEqual, "MOCKED!")

// short string -> no mock So(dep.Fun("Imtiny"), ShouldEqual, "Imtiny")

// how many invocations? convey.So(mock.Times(), convey.ShouldEqual, 2) // # of function invocations (mocked or not) convey.So(mock.MockTimes(), convey.ShouldEqual, 1) // # of mocked invocations only }) ```

Sequence support

```go PatchConvey("sequence support", t , func() { // # mockey v1.2.4+ mock := Mock(Fun).Return(Sequence("Alice").Times(3).Then("Bob").Then("Tom").Times(2)).Build()

r := Fun("something") convey.So(r, convey.ShouldEqual, "Alice")

r = Fun("something") convey.So(r, convey.ShouldEqual, "Alice")

r = Fun("something") convey.So(r, convey.ShouldEqual, "Alice")

r = Fun("something") convey.So(r, convey.ShouldEqual, "Bob")

r = Fun("something") convey.So(r, convey.ShouldEqual, "Tom")

...

convey.So(mock.Times(), convey.ShouldEqual, 5) convey.So(mock.MockTimes(), convey.ShouldEqual, 5) }) ```

Generics support

```go func GenericFunT any T { return t }

type GenericClass[T any] struct { }

func (g *GenericClass[T]) FunA(t T) T { return t }

...

PatchConvey("Generics function support", t, func() {

mock := MockGeneric(GenericFun[string]).Return("MOCKED!").Build() // or Mock(GenericFun[string], OptGeneric)

r := GenericFun("anything") // mocked num := GenericFun(2) // not mocked - type mismatch

convey.So(r, convey.ShouldEqual, "MOCKED!") convey.So(mock.Times(), convey.ShouldEqual, 1)

convey.So(num, convey.ShouldEqual, 2) })

PatchConvey("Generics class/method support", t, func() {

mock := MockGeneric((GenericClass[string]).FunA).Return("MOCKED!").Build() // or Mock((GenericClass[string]).FunA, OptGeneric)

genClass := &GenericClass[string]{}

r := genClass.FunA("anything")

convey.So(r, convey.ShouldEqual, "MOCKED!") convey.So(mock.Times(), convey.ShouldEqual, 1) })

```

Decorator mock

```go PatchConvey("decorator mock", t , func() { origin := Fun

mockFun := func(p string) string { origin(p) // call the original func return "b" // return something else }

mock := Mock(Fun).To(mockFun).Origin(&origin).Build()

r := Fun("anything") convey.So(r, convey.ShouldEqual, "b") convey.So(mock.Times(), convey.ShouldEqual, 1) }) ```

Goroutine inclusion/exclusion support

```go PatchConvey("filter go routine", t , func() { mock := Mock(Fun).ExcludeCurrentGoRoutine().Return("MOCKED!").Build() r := Fun("anything") convey.So(r, convey.ShouldEqual, "anything") convey.So(mock.Times(), convey.ShouldEqual, 1) convey.So(mock.MockTimes(), convey.ShouldEqual, 0)

mock.IncludeCurrentGoRoutine() r = Fun("anything") convey.So(r, convey.ShouldEqual, "MOCKED!") convey.So(mock.Times(), convey.ShouldEqual, 1) convey.So(mock.MockTimes(), convey.ShouldEqual, 1)

mock.IncludeCurrentGoRoutine() go Fun("anything") time.Sleep(1 * time.Second) convey.So(mock.Times(), convey.ShouldEqual, 1) convey.So(mock.MockTimes(), convey.ShouldEqual, 0) }) ```

PS: It's also possible to specify the goroutine where the mocking takes effect using mock.FilterGoRoutine

FAQ/troubleshooting

How to disable inline and compile optimization?

  1. Command line:go test -gcflags="all=-l -N" -v ./...
  2. Goland:fill -gcflags="all=-l -N" in the Run/Debug Configurations > Go tool arguments dialog box

The original function is still entered after mocking?

  1. Inline or compilation optimization is not disabled: you can try to use the debug mode. If you can run through it, it means that it is the problem. Please go to the relevant section of FAQ
  2. The Build() method was not called: forgot to call Build(), resulting in no actual effect
  3. Target function does not match exactly: ``go func TestXXX(t *testing.T) { Mock((*A).Foo).Return("c").Build() fmt.Println(A{}.Foo("a")) // enters the original function, because the mock target should beA.Foo`

a := A{} Mock(a.Foo).Return("c").Build() fmt.Println(a.Foo("a")) // enters the original function, because the mock target should be A.Foo or extracted from instance a using GetMethod } 4. The target function is executed in other goroutines: go func TestXXX(t *testing.T) { PatchConvey("TestXXX", t, func() { Mock(Foo).Return("c").Build() go Foo("a") // the timing of executing 'foo' is uncertain }) // when the main goroutine comes here, the relevant mock has been released by 'PatchConvey'. If 'foo' is executed before this, the mock succeeds, otherwise it fails fmt.Println("over") time.Sleep(time.Second) } ```

Error "function is too short to patch"?

  1. Inline or compilation optimization is not disabled: you can try to use the debug mode. If you can run through it, it means that it is the problem. Please go to the relevant section of FAQ
  2. The function is really too short: it means that the target function is less than one line, resulting in the compiled machine code being too short. Generally, two or more lines will not cause this problem
  3. Repeat mocking the same function: repeat mocking the same function in the PatchConvey of the smallest unit. If there is such a need, please get the Mocker instance and remock.
  4. Other tools mock this function: for example, monkey or other tools have mocked this function

License

Mockey is distributed under the Apache License, version 2.0. The licenses of third party dependencies of Mockey are explained here.

Owner

  • Name: Bytedance Inc.
  • Login: bytedance
  • Kind: organization
  • Location: Singapore

GitHub Events

Total
  • Create event: 3
  • Issues event: 19
  • Release event: 2
  • Watch event: 147
  • Issue comment event: 32
  • Push event: 3
  • Pull request event: 5
  • Pull request review event: 3
  • Fork event: 10
Last Year
  • Create event: 3
  • Issues event: 19
  • Release event: 2
  • Watch event: 147
  • Issue comment event: 32
  • Push event: 3
  • Pull request event: 5
  • Pull request review event: 3
  • Fork event: 10

Committers

Last synced: 9 months ago

All Time
  • Total Commits: 41
  • Total Committers: 9
  • Avg Commits per committer: 4.556
  • Development Distribution Score (DDS): 0.39
Past Year
  • Commits: 7
  • Committers: 4
  • Avg Commits per committer: 1.75
  • Development Distribution Score (DDS): 0.429
Top Committers
Name Email Commits
SYC_ s****a@g****m 25
ycydsxy s****7@t****n 9
violin0847 1****8@q****m 1
luoshiqi l****i@b****m 1
Willem Jiang w****g@g****m 1
许易冲 x****g@b****m 1
ycydsxy y****y@g****m 1
stefano.fratini s****i@b****m 1
Yuanhong Tan t****g@b****m 1
Committer Domains (Top 20 + Academic)

Issues and Pull Requests

Last synced: 6 months ago

All Time
  • Total issues: 43
  • Total pull requests: 42
  • Average time to close issues: 30 days
  • Average time to close pull requests: 15 days
  • Total issue authors: 36
  • Total pull request authors: 9
  • Average comments per issue: 1.95
  • Average comments per pull request: 0.31
  • Merged pull requests: 39
  • Bot issues: 0
  • Bot pull requests: 0
Past Year
  • Issues: 16
  • Pull requests: 6
  • Average time to close issues: 14 days
  • Average time to close pull requests: 1 day
  • Issue authors: 14
  • Pull request authors: 3
  • Average comments per issue: 1.94
  • Average comments per pull request: 0.0
  • Merged pull requests: 6
  • Bot issues: 0
  • Bot pull requests: 0
Top Authors
Issue Authors
  • Sychorius (4)
  • xiazemin (3)
  • ycydsxy (3)
  • SuCrayon (1)
  • qiansen1386 (1)
  • xulongfei (1)
  • pWoLiAn (1)
  • suguimanLogan (1)
  • peter-wangxu (1)
  • haoxins (1)
  • speed2exe (1)
  • mutezebra (1)
  • Tianion (1)
  • LAShZ (1)
  • amosnothing (1)
Pull Request Authors
  • Sychorius (29)
  • ycydsxy (9)
  • lsqlebai (2)
  • WillemJiang (2)
  • fratuz610 (2)
  • qinguoyi (2)
  • smallchimney (1)
  • le0tan (1)
  • test1389931913fj (1)
  • violin0847 (1)
Top Labels
Issue Labels
enhancement (3) bug (3) documentation (1) help wanted (1)
Pull Request Labels

Packages

  • Total packages: 6
  • Total downloads: unknown
  • Total docker downloads: 1,556
  • Total dependent packages: 69
    (may contain duplicates)
  • Total dependent repositories: 66
    (may contain duplicates)
  • Total versions: 133
proxy.golang.org: github.com/bytedance/mockey
  • Versions: 23
  • Dependent Packages: 69
  • Dependent Repositories: 66
  • Docker Downloads: 1,556
Rankings
Dependent packages count: 0.7%
Dependent repos count: 0.7%
Docker downloads count: 1.2%
Average: 3.0%
Stargazers count: 4.0%
Forks count: 8.4%
Last synced: 6 months ago
proxy.golang.org: github.com/byTEDance/mockey
  • Versions: 22
  • Dependent Packages: 0
  • Dependent Repositories: 0
Rankings
Dependent packages count: 5.3%
Average: 5.5%
Dependent repos count: 5.7%
Last synced: 6 months ago
proxy.golang.org: github.com/bytedANCE/mockey
  • Versions: 22
  • Dependent Packages: 0
  • Dependent Repositories: 0
Rankings
Dependent packages count: 5.3%
Average: 5.5%
Dependent repos count: 5.7%
Last synced: 6 months ago
proxy.golang.org: github.com/bytedance/mOCKEy
  • Versions: 22
  • Dependent Packages: 0
  • Dependent Repositories: 0
Rankings
Dependent packages count: 5.3%
Average: 5.5%
Dependent repos count: 5.7%
Last synced: 6 months ago
proxy.golang.org: github.com/Bytedance/mockey
  • Versions: 22
  • Dependent Packages: 0
  • Dependent Repositories: 0
Rankings
Dependent packages count: 5.7%
Average: 5.9%
Dependent repos count: 6.1%
Last synced: 6 months ago
proxy.golang.org: github.com/bytedance/Mockey
  • Versions: 22
  • Dependent Packages: 0
  • Dependent Repositories: 0
Rankings
Dependent packages count: 6.3%
Average: 6.5%
Dependent repos count: 6.7%
Last synced: 6 months ago

Dependencies

go.mod go
  • github.com/smartystreets/goconvey v1.6.4
  • golang.org/x/arch v0.0.0-20201008161808-52c3e6f60cff
go.sum go
  • github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1
  • github.com/jtolds/gls v4.20.0+incompatible
  • github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d
  • github.com/smartystreets/goconvey v1.6.4
  • golang.org/x/arch v0.0.0-20201008161808-52c3e6f60cff
  • golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2
  • golang.org/x/net v0.0.0-20190311183353-d8887717615a
  • golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a
  • golang.org/x/text v0.3.0
  • golang.org/x/tools v0.0.0-20190328211700-ab21143f2384
  • rsc.io/pdf v0.1.1
.github/workflows/pr-check.yml actions
  • actions/cache v3 composite
  • actions/checkout v3 composite
  • actions/setup-go v3 composite
  • apache/skywalking-eyes/header v0.4.0 composite
  • crate-ci/typos master composite
  • golangci/golangci-lint-action v3 composite
  • reviewdog/action-staticcheck v1 composite
.github/workflows/release-check.yml actions
  • actions/checkout v3 composite
.github/workflows/tests.yml actions
  • actions/checkout v3 composite
  • actions/setup-go v3 composite