controller.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  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 "sync"
  57. // A TestReporter is something that can be used to report test failures.
  58. // It is satisfied by the standard library's *testing.T.
  59. type TestReporter interface {
  60. Errorf(format string, args ...interface{})
  61. Fatalf(format string, args ...interface{})
  62. }
  63. // A Controller represents the top-level control of a mock ecosystem.
  64. // It defines the scope and lifetime of mock objects, as well as their expectations.
  65. // It is safe to call Controller's methods from multiple goroutines.
  66. type Controller struct {
  67. mu sync.Mutex
  68. t TestReporter
  69. expectedCalls callSet
  70. }
  71. func NewController(t TestReporter) *Controller {
  72. return &Controller{
  73. t: t,
  74. expectedCalls: make(callSet),
  75. }
  76. }
  77. func (ctrl *Controller) RecordCall(receiver interface{}, method string, args ...interface{}) *Call {
  78. // TODO: check arity, types.
  79. margs := make([]Matcher, len(args))
  80. for i, arg := range args {
  81. if m, ok := arg.(Matcher); ok {
  82. margs[i] = m
  83. } else if arg == nil {
  84. // Handle nil specially so that passing a nil interface value
  85. // will match the typed nils of concrete args.
  86. margs[i] = Nil()
  87. } else {
  88. margs[i] = Eq(arg)
  89. }
  90. }
  91. ctrl.mu.Lock()
  92. defer ctrl.mu.Unlock()
  93. call := &Call{t: ctrl.t, receiver: receiver, method: method, args: margs, minCalls: 1, maxCalls: 1}
  94. ctrl.expectedCalls.Add(call)
  95. return call
  96. }
  97. func (ctrl *Controller) Call(receiver interface{}, method string, args ...interface{}) []interface{} {
  98. ctrl.mu.Lock()
  99. defer ctrl.mu.Unlock()
  100. expected := ctrl.expectedCalls.FindMatch(receiver, method, args)
  101. if expected == nil {
  102. ctrl.t.Fatalf("no matching expected call: %T.%v(%v)", receiver, method, args)
  103. }
  104. // Two things happen here:
  105. // * the matching call no longer needs to check prerequite calls,
  106. // * and the prerequite calls are no longer expected, so remove them.
  107. preReqCalls := expected.dropPrereqs()
  108. for _, preReqCall := range preReqCalls {
  109. ctrl.expectedCalls.Remove(preReqCall)
  110. }
  111. rets, action := expected.call(args)
  112. if expected.exhausted() {
  113. ctrl.expectedCalls.Remove(expected)
  114. }
  115. // Don't hold the lock while doing the call's action (if any)
  116. // so that actions may execute concurrently.
  117. // We use the deferred Unlock to capture any panics that happen above;
  118. // here we add a deferred Lock to balance it.
  119. ctrl.mu.Unlock()
  120. defer ctrl.mu.Lock()
  121. if action != nil {
  122. action()
  123. }
  124. return rets
  125. }
  126. func (ctrl *Controller) Finish() {
  127. ctrl.mu.Lock()
  128. defer ctrl.mu.Unlock()
  129. // If we're currently panicking, probably because this is a deferred call,
  130. // pass through the panic.
  131. if err := recover(); err != nil {
  132. panic(err)
  133. }
  134. // Check that all remaining expected calls are satisfied.
  135. failures := false
  136. for _, methodMap := range ctrl.expectedCalls {
  137. for _, calls := range methodMap {
  138. for _, call := range calls {
  139. if !call.satisfied() {
  140. ctrl.t.Errorf("missing call(s) to %v", call)
  141. failures = true
  142. }
  143. }
  144. }
  145. }
  146. if failures {
  147. ctrl.t.Fatalf("aborting test due to missing call(s)")
  148. }
  149. }