ObjectManagerTest.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Framework\ObjectManager\Test\Unit;
  7. use Magento\Framework\ObjectManager\Factory\Dynamic\Developer;
  8. require __DIR__ . '/_files/ChildInterface.php';
  9. require __DIR__ . '/_files/DiParent.php';
  10. require __DIR__ . '/_files/Child.php';
  11. require __DIR__ . '/_files/Child/A.php';
  12. require __DIR__ . '/_files/Child/Circular.php';
  13. require __DIR__ . '/_files/Aggregate/AggregateInterface.php';
  14. require __DIR__ . '/_files/Aggregate/AggregateParent.php';
  15. require __DIR__ . '/_files/Aggregate/Child.php';
  16. require __DIR__ . '/_files/Aggregate/WithOptional.php';
  17. class ObjectManagerTest extends \PHPUnit\Framework\TestCase
  18. {
  19. /**
  20. * @var \Magento\Framework\ObjectManager\ObjectManager
  21. */
  22. protected $_object;
  23. protected function setUp()
  24. {
  25. $config = new \Magento\Framework\ObjectManager\Config\Config(
  26. new \Magento\Framework\ObjectManager\Relations\Runtime()
  27. );
  28. $factory = new Developer($config, null, null, [
  29. 'first_param' => 'first_param_value',
  30. 'second_param' => 'second_param_value'
  31. ]);
  32. $this->_object = new \Magento\Framework\ObjectManager\ObjectManager($factory, $config);
  33. $factory->setObjectManager($this->_object);
  34. }
  35. public function testCreateCreatesNewInstanceEveryTime()
  36. {
  37. $objectA = $this->_object->create(\Magento\Test\Di\Child::class);
  38. $this->assertInstanceOf(\Magento\Test\Di\Child::class, $objectA);
  39. $objectB = $this->_object->create(\Magento\Test\Di\Child::class);
  40. $this->assertInstanceOf(\Magento\Test\Di\Child::class, $objectB);
  41. $this->assertNotSame($objectA, $objectB);
  42. }
  43. public function testGetCreatesNewInstanceOnlyOnce()
  44. {
  45. $objectA = $this->_object->get(\Magento\Test\Di\Child::class);
  46. $this->assertInstanceOf(\Magento\Test\Di\Child::class, $objectA);
  47. $objectB = $this->_object->get(\Magento\Test\Di\Child::class);
  48. $this->assertInstanceOf(\Magento\Test\Di\Child::class, $objectB);
  49. $this->assertSame($objectA, $objectB);
  50. }
  51. public function testCreateCreatesPreferredImplementation()
  52. {
  53. $this->_object->configure(
  54. [
  55. 'preferences' => [
  56. \Magento\Test\Di\DiInterface::class => \Magento\Test\Di\DiParent::class,
  57. \Magento\Test\Di\DiParent::class => \Magento\Test\Di\Child::class,
  58. ],
  59. ]
  60. );
  61. $interface = $this->_object->create(\Magento\Test\Di\DiInterface::class);
  62. $parent = $this->_object->create(\Magento\Test\Di\DiParent::class);
  63. $child = $this->_object->create(\Magento\Test\Di\Child::class);
  64. $this->assertInstanceOf(\Magento\Test\Di\Child::class, $interface);
  65. $this->assertInstanceOf(\Magento\Test\Di\Child::class, $parent);
  66. $this->assertInstanceOf(\Magento\Test\Di\Child::class, $child);
  67. $this->assertNotSame($interface, $parent);
  68. $this->assertNotSame($interface, $child);
  69. }
  70. public function testGetCreatesPreferredImplementation()
  71. {
  72. $this->_object->configure(
  73. [
  74. 'preferences' => [
  75. \Magento\Test\Di\DiInterface::class => \Magento\Test\Di\DiParent::class,
  76. \Magento\Test\Di\DiParent::class => \Magento\Test\Di\Child::class,
  77. ],
  78. ]
  79. );
  80. $interface = $this->_object->get(\Magento\Test\Di\DiInterface::class);
  81. $parent = $this->_object->get(\Magento\Test\Di\DiParent::class);
  82. $child = $this->_object->get(\Magento\Test\Di\Child::class);
  83. $this->assertInstanceOf(\Magento\Test\Di\Child::class, $interface);
  84. $this->assertInstanceOf(\Magento\Test\Di\Child::class, $parent);
  85. $this->assertInstanceOf(\Magento\Test\Di\Child::class, $child);
  86. $this->assertSame($interface, $parent);
  87. $this->assertSame($interface, $child);
  88. }
  89. /**
  90. * @expectedException \BadMethodCallException
  91. * @expectedExceptionMessage Missing required argument $scalar of Magento\Test\Di\Aggregate\AggregateParent
  92. */
  93. public function testCreateThrowsExceptionIfRequiredConstructorParameterIsNotProvided()
  94. {
  95. $this->_object->configure(
  96. [
  97. 'preferences' => [
  98. \Magento\Test\Di\DiInterface::class => \Magento\Test\Di\DiParent::class,
  99. \Magento\Test\Di\DiParent::class => \Magento\Test\Di\Child::class,
  100. ],
  101. ]
  102. );
  103. $this->_object->create(\Magento\Test\Di\Aggregate\AggregateParent::class);
  104. }
  105. public function testCreateResolvesScalarParametersAutomatically()
  106. {
  107. $this->_object->configure(
  108. [
  109. 'preferences' => [
  110. \Magento\Test\Di\DiInterface::class => \Magento\Test\Di\DiParent::class,
  111. \Magento\Test\Di\DiParent::class => \Magento\Test\Di\Child::class,
  112. ],
  113. \Magento\Test\Di\Aggregate\AggregateParent::class => [
  114. 'arguments' => [
  115. 'child' => ['instance' => \Magento\Test\Di\Child\A::class],
  116. 'scalar' => 'scalarValue',
  117. ],
  118. ],
  119. ]
  120. );
  121. /** @var $result \Magento\Test\Di\Aggregate\AggregateParent */
  122. $result = $this->_object->create(\Magento\Test\Di\Aggregate\AggregateParent::class);
  123. $this->assertInstanceOf(\Magento\Test\Di\Aggregate\AggregateParent::class, $result);
  124. $this->assertInstanceOf(\Magento\Test\Di\Child::class, $result->interface);
  125. $this->assertInstanceOf(\Magento\Test\Di\Child::class, $result->parent);
  126. $this->assertInstanceOf(\Magento\Test\Di\Child\A::class, $result->child);
  127. $this->assertEquals('scalarValue', $result->scalar);
  128. $this->assertEquals('1', $result->optionalScalar);
  129. }
  130. public function testGetCreatesSharedInstancesEveryTime()
  131. {
  132. $this->_object->configure(
  133. [
  134. 'preferences' => [
  135. \Magento\Test\Di\DiInterface::class => \Magento\Test\Di\DiParent::class,
  136. \Magento\Test\Di\DiParent::class => \Magento\Test\Di\Child::class,
  137. ],
  138. \Magento\Test\Di\DiInterface::class => ['shared' => 0],
  139. \Magento\Test\Di\Aggregate\AggregateParent::class => [
  140. 'arguments' => ['scalar' => 'scalarValue'],
  141. ],
  142. ]
  143. );
  144. /** @var $result \Magento\Test\Di\Aggregate\AggregateParent */
  145. $result = $this->_object->create(\Magento\Test\Di\Aggregate\AggregateParent::class);
  146. $this->assertInstanceOf(\Magento\Test\Di\Aggregate\AggregateParent::class, $result);
  147. $this->assertInstanceOf(\Magento\Test\Di\Child::class, $result->interface);
  148. $this->assertInstanceOf(\Magento\Test\Di\Child::class, $result->parent);
  149. $this->assertInstanceOf(\Magento\Test\Di\Child::class, $result->child);
  150. $this->assertNotSame($result->interface, $result->parent);
  151. $this->assertNotSame($result->interface, $result->child);
  152. $this->assertSame($result->parent, $result->child);
  153. }
  154. /**
  155. * @expectedException \LogicException
  156. * @expectedExceptionMessage Circular dependency: Magento\Test\Di\Aggregate\AggregateParent depends on
  157. * Magento\Test\Di\Child\Circular and vice versa.
  158. */
  159. public function testGetDetectsCircularDependency()
  160. {
  161. $this->_object->configure(
  162. [
  163. 'preferences' => [
  164. \Magento\Test\Di\DiInterface::class => \Magento\Test\Di\DiParent::class,
  165. \Magento\Test\Di\DiParent::class => \Magento\Test\Di\Child\Circular::class,
  166. ],
  167. ]
  168. );
  169. $this->_object->create(\Magento\Test\Di\Aggregate\AggregateParent::class);
  170. }
  171. public function testCreateIgnoresOptionalArguments()
  172. {
  173. $instance = $this->_object->create(\Magento\Test\Di\Aggregate\WithOptional::class);
  174. $this->assertNull($instance->parent);
  175. $this->assertNull($instance->child);
  176. }
  177. public function testCreateCreatesPreconfiguredInstance()
  178. {
  179. $this->_object->configure(
  180. [
  181. 'preferences' => [
  182. \Magento\Test\Di\DiInterface::class => \Magento\Test\Di\DiParent::class,
  183. \Magento\Test\Di\DiParent::class => \Magento\Test\Di\Child::class,
  184. ],
  185. 'customChildType' => [
  186. 'type' => \Magento\Test\Di\Aggregate\Child::class,
  187. 'arguments' => [
  188. 'scalar' => 'configuredScalar',
  189. 'secondScalar' => 'configuredSecondScalar',
  190. 'secondOptionalScalar' => 'configuredOptionalScalar',
  191. ],
  192. ],
  193. ]
  194. );
  195. $customChild = $this->_object->get('customChildType');
  196. $this->assertInstanceOf(\Magento\Test\Di\Aggregate\Child::class, $customChild);
  197. $this->assertEquals('configuredScalar', $customChild->scalar);
  198. $this->assertEquals('configuredSecondScalar', $customChild->secondScalar);
  199. $this->assertEquals(1, $customChild->optionalScalar);
  200. $this->assertEquals('configuredOptionalScalar', $customChild->secondOptionalScalar);
  201. $this->assertSame($customChild, $this->_object->get('customChildType'));
  202. }
  203. public function testParameterShareabilityConfigurationIsApplied()
  204. {
  205. $this->_object->configure(
  206. [
  207. 'customChildType' => [
  208. 'type' => \Magento\Test\Di\Aggregate\Child::class,
  209. 'arguments' => [
  210. 'interface' => ['instance' => \Magento\Test\Di\DiParent::class],
  211. 'scalar' => 'configuredScalar',
  212. 'secondScalar' => 'configuredSecondScalar',
  213. ],
  214. ],
  215. ]
  216. );
  217. $childA = $this->_object->create('customChildType');
  218. $childB = $this->_object->create('customChildType');
  219. $this->assertNotSame($childA, $childB);
  220. $this->assertSame($childA->interface, $childB->interface);
  221. $this->_object->configure(
  222. [
  223. 'customChildType' => [
  224. 'arguments' => [
  225. 'interface' => [
  226. 'instance' => \Magento\Test\Di\DiParent::class,
  227. 'shared' => false,
  228. ],
  229. ],
  230. ],
  231. ]
  232. );
  233. $childA = $this->_object->create('customChildType');
  234. $childB = $this->_object->create('customChildType');
  235. $this->assertNotSame($childA, $childB);
  236. $this->assertNotSame($childA->interface, $childB->interface);
  237. }
  238. public function testTypeShareabilityConfigurationIsApplied()
  239. {
  240. $this->_object->configure(
  241. [
  242. 'customChildType' => [
  243. 'type' => \Magento\Test\Di\Aggregate\Child::class,
  244. 'arguments' => [
  245. 'interface' => ['instance' => \Magento\Test\Di\DiParent::class],
  246. 'scalar' => 'configuredScalar',
  247. 'secondScalar' => 'configuredSecondScalar',
  248. ],
  249. ],
  250. ]
  251. );
  252. $childA = $this->_object->create('customChildType');
  253. $childB = $this->_object->create('customChildType');
  254. $this->assertNotSame($childA, $childB);
  255. $this->assertSame($childA->interface, $childB->interface);
  256. $this->_object->configure([\Magento\Test\Di\DiParent::class => ['shared' => false]]);
  257. $parent1 = $this->_object->create(\Magento\Test\Di\DiParent::class);
  258. $parent2 = $this->_object->create(\Magento\Test\Di\DiParent::class);
  259. $this->assertNotSame($parent1, $parent2);
  260. $childA = $this->_object->create('customChildType');
  261. $childB = $this->_object->create('customChildType');
  262. $this->assertNotSame($childA, $childB);
  263. }
  264. public function testParameterShareabilityConfigurationOverridesTypeShareability()
  265. {
  266. $this->_object->configure(
  267. [
  268. \Magento\Test\Di\DiParent::class => ['shared' => false],
  269. 'customChildType' => [
  270. 'type' => \Magento\Test\Di\Aggregate\Child::class,
  271. 'arguments' => [
  272. 'interface' => ['instance' => \Magento\Test\Di\DiParent::class],
  273. 'scalar' => 'configuredScalar',
  274. 'secondScalar' => 'configuredSecondScalar',
  275. ],
  276. ],
  277. ]
  278. );
  279. $childA = $this->_object->create('customChildType');
  280. $childB = $this->_object->create('customChildType');
  281. $this->assertNotSame($childA, $childB);
  282. $this->assertNotSame($childA->interface, $childB->interface);
  283. $this->_object->configure(
  284. [
  285. 'customChildType' => [
  286. 'arguments' => [
  287. 'interface' => [
  288. 'instance' => \Magento\Test\Di\DiParent::class,
  289. 'shared' => true,
  290. ],
  291. ],
  292. ],
  293. ]
  294. );
  295. $childA = $this->_object->create('customChildType');
  296. $childB = $this->_object->create('customChildType');
  297. $this->assertNotSame($childA, $childB);
  298. $this->assertSame($childA->interface, $childB->interface);
  299. }
  300. public function testGlobalArgumentsCanBeConfigured()
  301. {
  302. $this->_object->configure(
  303. [
  304. 'preferences' => [
  305. \Magento\Test\Di\DiInterface::class => \Magento\Test\Di\DiParent::class
  306. ],
  307. \Magento\Test\Di\Aggregate\AggregateParent::class => [
  308. 'arguments' => [
  309. 'scalar' => ['argument' => 'first_param'],
  310. 'optionalScalar' => ['argument' => 'second_param'],
  311. ],
  312. ],
  313. ]
  314. );
  315. /** @var $result \Magento\Test\Di\Aggregate\AggregateParent */
  316. $result = $this->_object->create(\Magento\Test\Di\Aggregate\AggregateParent::class);
  317. $this->assertEquals('first_param_value', $result->scalar);
  318. $this->assertEquals('second_param_value', $result->optionalScalar);
  319. }
  320. public function testConfiguredArgumentsAreInherited()
  321. {
  322. $this->_object->configure(
  323. [\Magento\Test\Di\Aggregate\AggregateParent::class => [
  324. 'arguments' => [
  325. 'interface' => ['instance' => \Magento\Test\Di\DiParent::class],
  326. 'scalar' => ['argument' => 'first_param'],
  327. 'optionalScalar' => 'parentOptionalScalar',
  328. ],
  329. ], \Magento\Test\Di\Aggregate\Child::class => [
  330. 'arguments' => [
  331. 'secondScalar' => 'childSecondScalar',
  332. ],
  333. ],
  334. ]
  335. );
  336. /** @var $result \Magento\Test\Di\Aggregate\Child */
  337. $result = $this->_object->create(\Magento\Test\Di\Aggregate\Child::class);
  338. $this->assertInstanceOf(\Magento\Test\Di\DiParent::class, $result->interface);
  339. $this->assertEquals('first_param_value', $result->scalar);
  340. $this->assertEquals('childSecondScalar', $result->secondScalar);
  341. $this->assertEquals('parentOptionalScalar', $result->optionalScalar);
  342. }
  343. public function testConfiguredArgumentsOverrideInheritedArguments()
  344. {
  345. $this->_object->configure(
  346. [
  347. \Magento\Test\Di\Aggregate\AggregateParent::class => [
  348. 'arguments' => [
  349. 'interface' => ['instance' => \Magento\Test\Di\DiParent::class],
  350. 'scalar' => ['argument' => 'first_param'],
  351. 'optionalScalar' => 'parentOptionalScalar',
  352. ],
  353. ],
  354. \Magento\Test\Di\Aggregate\Child::class => [
  355. 'arguments' => [
  356. 'interface' => ['instance' => \Magento\Test\Di\Child::class],
  357. 'scalar' => ['argument' => 'second_param'],
  358. 'secondScalar' => 'childSecondScalar',
  359. 'optionalScalar' => 'childOptionalScalar',
  360. ],
  361. ],
  362. ]
  363. );
  364. /** @var $result \Magento\Test\Di\Aggregate\Child */
  365. $result = $this->_object->create(\Magento\Test\Di\Aggregate\Child::class);
  366. $this->assertInstanceOf(\Magento\Test\Di\Child::class, $result->interface);
  367. $this->assertEquals('second_param_value', $result->scalar);
  368. $this->assertEquals('childSecondScalar', $result->secondScalar);
  369. $this->assertEquals('childOptionalScalar', $result->optionalScalar);
  370. }
  371. public function testGetIgnoresFirstSlash()
  372. {
  373. $this->assertSame(
  374. $this->_object->get(\Magento\Test\Di\Child::class),
  375. $this->_object->get('\\' . \Magento\Test\Di\Child::class)
  376. );
  377. }
  378. }