/**
  * Creates a mock from the target class
  *
  * @param string $class
  * @param array $args
  * @param array $spec
  *
  * @return \PHPUnit_Framework_MockObject_MockObject
  */
 private function _setupTarget_setupMock($class, $args, $spec)
 {
     /*
      * $spec = ['method', 'method', ...]
      * $spec = [
      *      'method' => int,
      *      'method' => [ 'count' => int, 'with' => mixed, 'return' => mixed ]
      * ],
      *
      */
     if (is_string($spec)) {
         $mock = $this->{$spec}();
     } else {
         $call = function ($spec) {
             $cb = [$this, $spec[0]];
             $args = isset($spec[1]) ? (array) $spec[1] : false;
             if ($args) {
                 return call_user_func_array($cb, $args);
             }
             return $this->{$cb}();
         };
         $methods = [];
         $methodMocks = [];
         foreach ($spec as $method => $methodSpec) {
             if (is_int($method)) {
                 $methods[] = $methodSpec;
                 continue;
             }
             if (is_string($methodSpec)) {
                 $methodSpec = $this->{$methodSpec}();
             }
             $methods[] = $method;
             $methodMocks[$method] = ['expects' => isset($methodSpec['count']) ? $this->exactly($methodSpec['count']) : $this->any(), 'with' => isset($methodSpec['@with']) ? $call($methodSpec['@with']) : (isset($methodSpec['with']) ? $methodSpec['with'] : null), 'return' => isset($methodSpec['@return']) ? $call($methodSpec['@return']) : (isset($methodSpec['return']) ? '__self__' == $methodSpec['return'] ? $this->returnSelf() : $this->returnValue($methodSpec['return']) : null)];
         }
         $mockBuilder = $this->getMockBuilder($class)->setMethods($methods);
         if (false === $args) {
             $mockBuilder->disableOriginalConstructor();
         } else {
             $mockBuilder->setConstructorArgs(InstanceCreator::mapArray($args));
         }
         $mock = $mockBuilder->getMock();
         foreach ($methodMocks as $method => $mockSpec) {
             $methodMock = $mock->expects($mockSpec['expects'])->method($method);
             if ($mockSpec['with']) {
                 $methodMock->with($mockSpec['with']);
             }
             if ($mockSpec['return']) {
                 $methodMock->will($mockSpec['return']);
             }
         }
     }
     return $mock;
 }