controller.go 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. // Copyright 2010 Google Inc.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. // GoMock - a mock framework for Go.
  15. //
  16. // Standard usage:
  17. // (1) Define an interface that you wish to mock.
  18. // type MyInterface interface {
  19. // SomeMethod(x int64, y string)
  20. // }
  21. // (2) Use mockgen to generate a mock from the interface.
  22. // (3) Use the mock in a test:
  23. // func TestMyThing(t *testing.T) {
  24. // mockCtrl := gomock.NewController(t)
  25. // defer mockCtrl.Finish()
  26. //
  27. // mockObj := something.NewMockMyInterface(mockCtrl)
  28. // mockObj.EXPECT().SomeMethod(4, "blah")
  29. // // pass mockObj to a real object and play with it.
  30. // }
  31. //
  32. // By default, expected calls are not enforced to run in any particular order.
  33. // Call order dependency can be enforced by use of InOrder and/or Call.After.
  34. // Call.After can create more varied call order dependencies, but InOrder is
  35. // often more convenient.
  36. //
  37. // The following examples create equivalent call order dependencies.
  38. //
  39. // Example of using Call.After to chain expected call order:
  40. //
  41. // firstCall := mockObj.EXPECT().SomeMethod(1, "first")
  42. // secondCall := mockObj.EXPECT().SomeMethod(2, "second").After(firstCall)
  43. // mockObj.EXPECT().SomeMethod(3, "third").After(secondCall)
  44. //
  45. // Example of using InOrder to declare expected call order:
  46. //
  47. // gomock.InOrder(
  48. // mockObj.EXPECT().SomeMethod(1, "first"),
  49. // mockObj.EXPECT().SomeMethod(2, "second"),
  50. // mockObj.EXPECT().SomeMethod(3, "third"),
  51. // )
  52. //
  53. // TODO:
  54. // - Handle different argument/return types (e.g. ..., chan, map, interface).
  55. package gomock
  56. import (
  57. "fmt"
  58. "reflect"
  59. "sync"
  60. )
  61. // A TestReporter is something that can be used to report test failures.
  62. // It is satisfied by the standard library's *testing.T.
  63. type TestReporter interface {
  64. Errorf(format string, args ...interface{})
  65. Fatalf(format string, args ...interface{})
  66. }
  67. // A Controller represents the top-level control of a mock ecosystem.
  68. // It defines the scope and lifetime of mock objects, as well as their expectations.
  69. // It is safe to call Controller's methods from multiple goroutines.
  70. type Controller struct {
  71. mu sync.Mutex
  72. t TestReporter
  73. expectedCalls callSet
  74. }
  75. func NewController(t TestReporter) *Controller {
  76. return &Controller{
  77. t: t,
  78. expectedCalls: make(callSet),
  79. }
  80. }
  81. func (ctrl *Controller) RecordCall(receiver interface{}, method string, args ...interface{}) *Call {
  82. recv := reflect.ValueOf(receiver)
  83. for i := 0; i < recv.Type().NumMethod(); i++ {
  84. if recv.Type().Method(i).Name == method {
  85. return ctrl.RecordCallWithMethodType(receiver, method, recv.Method(i).Type(), args...)
  86. }
  87. }
  88. ctrl.t.Fatalf("gomock: failed finding method %s on %T", method, receiver)
  89. // In case t.Fatalf does not panic.
  90. panic(fmt.Sprintf("gomock: failed finding method %s on %T", method, receiver))
  91. }
  92. func (ctrl *Controller) RecordCallWithMethodType(receiver interface{}, method string, methodType reflect.Type, args ...interface{}) *Call {
  93. // TODO: check arity, types.
  94. margs := make([]Matcher, len(args))
  95. for i, arg := range args {
  96. if m, ok := arg.(Matcher); ok {
  97. margs[i] = m
  98. } else if arg == nil {
  99. // Handle nil specially so that passing a nil interface value
  100. // will match the typed nils of concrete args.
  101. margs[i] = Nil()
  102. } else {
  103. margs[i] = Eq(arg)
  104. }
  105. }
  106. ctrl.mu.Lock()
  107. defer ctrl.mu.Unlock()
  108. call := &Call{t: ctrl.t, receiver: receiver, method: method, methodType: methodType, args: margs, minCalls: 1, maxCalls: 1}
  109. ctrl.expectedCalls.Add(call)
  110. return call
  111. }
  112. func (ctrl *Controller) Call(receiver interface{}, method string, args ...interface{}) []interface{} {
  113. ctrl.mu.Lock()
  114. defer ctrl.mu.Unlock()
  115. expected := ctrl.expectedCalls.FindMatch(receiver, method, args)
  116. if expected == nil {
  117. ctrl.t.Fatalf("no matching expected call: %T.%v(%v)", receiver, method, args)
  118. }
  119. // Two things happen here:
  120. // * the matching call no longer needs to check prerequite calls,
  121. // * and the prerequite calls are no longer expected, so remove them.
  122. preReqCalls := expected.dropPrereqs()
  123. for _, preReqCall := range preReqCalls {
  124. ctrl.expectedCalls.Remove(preReqCall)
  125. }
  126. rets, action := expected.call(args)
  127. if expected.exhausted() {
  128. ctrl.expectedCalls.Remove(expected)
  129. }
  130. // Don't hold the lock while doing the call's action (if any)
  131. // so that actions may execute concurrently.
  132. // We use the deferred Unlock to capture any panics that happen above;
  133. // here we add a deferred Lock to balance it.
  134. ctrl.mu.Unlock()
  135. defer ctrl.mu.Lock()
  136. if action != nil {
  137. action()
  138. }
  139. return rets
  140. }
  141. func (ctrl *Controller) Finish() {
  142. ctrl.mu.Lock()
  143. defer ctrl.mu.Unlock()
  144. // If we're currently panicking, probably because this is a deferred call,
  145. // pass through the panic.
  146. if err := recover(); err != nil {
  147. panic(err)
  148. }
  149. // Check that all remaining expected calls are satisfied.
  150. failures := false
  151. for _, methodMap := range ctrl.expectedCalls {
  152. for _, calls := range methodMap {
  153. for _, call := range calls {
  154. if !call.satisfied() {
  155. ctrl.t.Errorf("missing call(s) to %v", call)
  156. failures = true
  157. }
  158. }
  159. }
  160. }
  161. if failures {
  162. ctrl.t.Fatalf("aborting test due to missing call(s)")
  163. }
  164. }