github.com/bytedance/mockey@v1.2.10/README.md (about)

     1  # Mockey
     2  
     3  English | [中文](README_cn.md)
     4  
     5  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. The bottom layer is monkey patch realized by rewriting function instructions at runtime.
     6  
     7  > 1. **inlining and compilation optimization need to be disabled** during compilation, otherwise mock may fail or an error may be reported. See the following [FAQ](#FAQ) chapter for details.
     8  > 2. In the actual process of writing a unit test, it is recommended to use it together with the [Convey](https://github.com/smartystreets/goconvey) library.
     9  
    10  ## Install
    11  ```
    12  go get github.com/bytedance/mockey@latest
    13  ```
    14  
    15  ## Quick Guide
    16  ```go
    17  import (
    18  	"fmt"
    19  	"testing"
    20  
    21  	. "github.com/bytedance/mockey"
    22  	. "github.com/smartystreets/goconvey/convey"
    23  )
    24  
    25  func Foo(in string) string {
    26  	return in
    27  }
    28  
    29  type A struct{}
    30  
    31  func (a A) Foo(in string) string { return in }
    32  
    33  var Bar = 0
    34  
    35  func TestMockXXX(t *testing.T) {
    36  	PatchConvey("TestMockXXX", t, func() {
    37  		Mock(Foo).Return("c").Build()   // mock function
    38  		Mock(A.Foo).Return("c").Build() // mock method
    39  		MockValue(&Bar).To(1)           // mock variable
    40  
    41  		So(Foo("a"), ShouldEqual, "c")        // assert `Foo` is mocked
    42  		So(new(A).Foo("b"), ShouldEqual, "c") // assert `A.Foo` is mocked
    43  		So(Bar, ShouldEqual, 1)               // assert `Bar` is mocked
    44  	})
    45  	// mock is released automatically outside `PatchConvey`
    46  	fmt.Println(Foo("a"))        // a
    47  	fmt.Println(new(A).Foo("b")) // b
    48  	fmt.Println(Bar)             // 0
    49  }
    50  ```
    51  ## Features
    52  - Mock functions and methods
    53      - Basic 
    54        - Common / variant parameter function 
    55        - Common / variant parameter method
    56        - Nested structure method
    57        - Export method of private type (under different packages)
    58      - Advanced
    59        - Execute the original function after mocking 
    60        - Goroutine conditional filtering
    61        - Incrementally change mock behavior
    62        - Get the execution times of target function
    63        - Get the execution times of mock function
    64  - Mock variable
    65    - Common variable
    66    - Function variable
    67  
    68  ## Compatibility
    69  ### OS Support
    70  - Mac OS(Darwin)
    71  - Linux
    72  - Windows
    73  ### Arch Support 
    74  - AMD64
    75  - ARM64
    76  ### Version Support 
    77  - Go 1.13+
    78  
    79  ## License
    80  Mockey is distributed under the [Apache License](https://github.com/bytedance/mockey/blob/main/LICENSE-APACHE), version 2.0. The licenses of third party dependencies of Mockey are explained [here](https://github.com/bytedance/mockey/blob/main/licenses).
    81  
    82  ## FAQ
    83  
    84  ### How to disable inline and compile optimization?
    85  1. Command line:`go test -gcflags="all=-l -N" -v ./...`
    86  2. Goland:fill `-gcflags="all=-l -N"` in the **Run/Debug Configurations > Go tool arguments** dialog box
    87  
    88  ### The original function is still entered after mocking?
    89  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](#how-to-disable-inline-and-compile-optimization) of FAQ
    90  3. The `Build()` method was not called: forgot to call `Build()`, resulting in no actual effect
    91  4. Target function does not match exactly:
    92  ```go
    93  func TestXXX(t *testing.T) {
    94     Mock((*A).Foo).Return("c").Build()
    95     fmt.Println(A{}.Foo("a")) // enters the original function, because the mock target should be `A.Foo`
    96  
    97     a := A{}
    98     Mock(a.Foo).Return("c").Build()
    99     fmt.Println(a.Foo("a")) // enters the original function, because the mock target should be `A.Foo` or extracted from instance `a` using `GetMethod`
   100  }
   101  ```
   102  4. The target function is executed in other goroutines:
   103  ```go
   104  func TestXXX(t *testing.T) {
   105     PatchConvey("TestXXX", t, func() {
   106        Mock(Foo).Return("c").Build()
   107        go Foo("a") // the timing of executing 'foo' is uncertain
   108     })
   109     // 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
   110     fmt.Println("over")
   111     time.Sleep(time.Second)
   112  }
   113  ```
   114  
   115  ### Error "function is too short to patch"?
   116  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](#how-to-disable-inline-and-compile-optimization) of FAQ
   117  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
   118  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.
   119  4. Other tools mock this function: for example, [monkey](https://github.com/bouk/monkey) or other tools have mocked this function