Skip to content

Commit 14c459d

Browse files
committed
AC-15503: PHPUnit 12: Upgrade Advanced, Tax & Integration related test cases
1 parent 5a5fa68 commit 14c459d

File tree

6 files changed

+128
-69
lines changed

6 files changed

+128
-69
lines changed

app/code/Magento/Integration/Test/Unit/Model/Config/Consolidated/_files/integration.xml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@
55
* All Rights Reserved.
66
*/
77
-->
8-
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
9-
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Integration:etc/integration/integration.xsd">
8+
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Integration:etc/integration/integration.xsd">
109
<integration name="TestIntegration1">
1110
<email>[email protected]</email>
1211
<endpoint_url>http://endpoint.com</endpoint_url>

app/code/Magento/Integration/Test/Unit/Model/ResourceModel/Oauth/ConsumerTest.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
namespace Magento\Integration\Test\Unit\Model\ResourceModel\Oauth;
99

10+
use \Magento\Integration\Model\ResourceModel\Oauth\Consumer as ConsumerResourceModel;
1011
use Magento\Framework\App\ObjectManager as AppObjectManager;
1112
use Magento\Framework\App\ResourceConnection;
1213
use Magento\Framework\DB\Adapter\AdapterInterface;
@@ -21,7 +22,7 @@
2122
use PHPUnit\Framework\TestCase;
2223

2324
/**
24-
* Unit test for \Magento\Integration\Model\ResourceModel\Oauth\Consumer
25+
* Unit test for ConsumerResourceModel
2526
*/
2627
class ConsumerTest extends TestCase
2728
{
@@ -43,7 +44,7 @@ class ConsumerTest extends TestCase
4344
protected $consumerMock;
4445

4546
/**
46-
* @var \Magento\Integration\Model\ResourceModel\Oauth\Consumer
47+
* @var ConsumerResourceModel
4748
*/
4849
protected $consumerResource;
4950

@@ -66,7 +67,7 @@ protected function setUp(): void
6667
$objectManagerMock = $this->createMock(ObjectManagerInterface::class);
6768
AppObjectManager::setInstance($objectManagerMock);
6869

69-
$this->consumerResource = new \Magento\Integration\Model\ResourceModel\Oauth\Consumer(
70+
$this->consumerResource = new ConsumerResourceModel(
7071
$contextMock,
7172
new DateTime()
7273
);
@@ -76,7 +77,7 @@ public function testAfterDelete(): void
7677
{
7778
$this->connectionMock->expects($this->exactly(2))->method('delete');
7879
$this->assertInstanceOf(
79-
\Magento\Integration\Model\ResourceModel\Oauth\Consumer::class,
80+
ConsumerResourceModel::class,
8081
$this->consumerResource->_afterDelete($this->consumerMock)
8182
);
8283
}

app/code/Magento/Tax/Test/Unit/Model/Calculation/CalculatorFactoryTest.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
use Magento\Tax\Model\Calculation\CalculatorFactory;
1515
use Magento\Tax\Model\Calculation\RowBaseCalculator;
1616
use Magento\Tax\Model\Calculation\TotalBaseCalculator;
17-
1817
use Magento\Tax\Model\Calculation\UnitBaseCalculator;
1918
use PHPUnit\Framework\Attributes\DataProvider;
2019
use PHPUnit\Framework\TestCase;
@@ -126,7 +125,7 @@ public function testCreate(
126125

127126
protected function getMockForAddress()
128127
{
129-
$address = $this->createMock(\Magento\Customer\Api\Data\AddressInterface::class);
128+
$address = $this->createMock(CustomerAddress::class);
130129

131130
return $address;
132131
}

app/code/Magento/Tax/Test/Unit/Model/TaxClass/Source/CustomerTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
class CustomerTest extends TestCase
2727
{
28-
use MockCreationTrait;
28+
// use MockCreationTrait;
2929

3030
/**
3131
* @var TaxClassRepositoryInterface|MockObject

app/code/Magento/Tax/Test/Unit/Observer/GetPriceConfigurationObserverTest.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
namespace Magento\Tax\Test\Unit\Observer;
99

1010
use Magento\Bundle\Model\ResourceModel\Selection\Collection;
11+
use Magento\Bundle\Model\Product\Type as BundleProductType;
1112
use Magento\Catalog\Model\Product;
1213
use Magento\Catalog\Model\Product\Type;
1314
use Magento\Catalog\Pricing\Price\BasePrice;
@@ -130,7 +131,7 @@ public function testExecute(array $testArray, array $expectedArray): void
130131
);
131132

132133
$product = $this->createPartialMockWithReflection(
133-
\Magento\Bundle\Model\Product\Type::class,
134+
BundleProductType::class,
134135
['getTypeInstance', 'getTypeId', 'getStoreId', 'getId', 'getSelectionsCollection']
135136
);
136137
$product->expects($this->any())

app/code/Magento/Tax/Test/Unit/Ui/DataProvider/Product/Listing/Collector/TaxTest.php

Lines changed: 118 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -17,67 +17,84 @@
1717
use Magento\Catalog\Pricing\Price\FinalPrice;
1818
use Magento\Framework\Pricing\Amount\AmountInterface;
1919
use Magento\Framework\Pricing\PriceCurrencyInterface;
20+
use Magento\Framework\Pricing\PriceInfoInterface as FrameworkPriceInfoInterface;
2021
use Magento\Framework\TestFramework\Unit\Helper\MockCreationTrait;
2122
use Magento\Tax\Ui\DataProvider\Product\Listing\Collector\Tax;
2223
use PHPUnit\Framework\MockObject\MockObject;
2324
use PHPUnit\Framework\TestCase;
2425

26+
/**
27+
* Unit test for Tax collector
28+
*
29+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
30+
*/
2531
class TaxTest extends TestCase
2632
{
2733
use MockCreationTrait;
2834

2935
/**
3036
* @var Tax
3137
*/
32-
protected $model;
38+
private Tax $model;
3339

3440
/**
3541
* @var PriceCurrencyInterface|MockObject
3642
*/
37-
protected $priceCurrencyMock;
43+
private MockObject $priceCurrencyMock;
3844

3945
/**
4046
* @var PriceInfoInterface|MockObject
4147
*/
42-
private $priceMock;
48+
private MockObject $renderPriceInfoMock;
4349

4450
/**
4551
* @var PriceInfoInterfaceFactory|MockObject
4652
*/
47-
private $priceInfoFactory;
53+
private MockObject $priceInfoFactory;
4854

4955
/**
5056
* @var PriceInfoExtensionInterface|MockObject
5157
*/
52-
private $extensionAttributes;
58+
private MockObject $extensionAttributes;
5359

5460
/**
5561
* @var PriceInfoExtensionInterfaceFactory|MockObject
5662
*/
57-
private $priceInfoExtensionFactory;
63+
private MockObject $priceInfoExtensionFactory;
5864

5965
/**
6066
* @var FormattedPriceInfoBuilder|MockObject
6167
*/
62-
private $formattedPriceInfoBuilder;
68+
private MockObject $formattedPriceInfoBuilder;
69+
70+
/**
71+
* @var FrameworkPriceInfoInterface|MockObject
72+
*/
73+
private MockObject $frameworkPriceInfoMock;
6374

6475
protected function setUp(): void
6576
{
6677
$this->priceCurrencyMock = $this->createMock(PriceCurrencyInterface::class);
6778

68-
// PriceInfoInterface: The test needs to mock getPrice() which doesn't exist in the interface
69-
// This is a test design issue - ideally should mock a concrete implementation
70-
// Workaround: Using getMockBuilder()->getMock() which allows any method configuration in PHPUnit 12
71-
$this->priceMock = $this->getMockBuilder(PriceInfoInterface::class)
72-
->disableOriginalConstructor()
73-
->getMock();
74-
75-
// Note: PriceInfoExtensionInterface is a generated extension attribute interface
76-
// Using createMock would fail as the interface doesn't exist until DI compilation
77-
// Keeping original approach but migrated to PHPUnit 12
78-
$this->extensionAttributes = $this->getMockBuilder(PriceInfoExtensionInterface::class)
79-
->disableOriginalConstructor()
80-
->getMock();
79+
// PriceInfoInterface (Catalog API) - used for product render DTO
80+
$this->renderPriceInfoMock = $this->createMock(PriceInfoInterface::class);
81+
82+
// PriceInfoExtensionInterface is a generated extension attribute interface
83+
// All interface methods must be included when using createPartialMockWithReflection
84+
$this->extensionAttributes = $this->createPartialMockWithReflection(
85+
PriceInfoExtensionInterface::class,
86+
[
87+
// All interface methods from generated interface
88+
'getMsrp',
89+
'setMsrp',
90+
'getTaxAdjustments',
91+
'setTaxAdjustments',
92+
'getWeeeAttributes',
93+
'setWeeeAttributes',
94+
'getWeeeAdjustment',
95+
'setWeeeAdjustment'
96+
]
97+
);
8198

8299
$this->priceInfoFactory = $this->getMockBuilder(PriceInfoInterfaceFactory::class)
83100
->disableOriginalConstructor()
@@ -88,9 +105,11 @@ protected function setUp(): void
88105
->disableOriginalConstructor()
89106
->onlyMethods(['create'])
90107
->getMock();
91-
$this->formattedPriceInfoBuilder = $this->getMockBuilder(FormattedPriceInfoBuilder::class)
92-
->disableOriginalConstructor()
93-
->getMock();
108+
109+
$this->formattedPriceInfoBuilder = $this->createMock(FormattedPriceInfoBuilder::class);
110+
111+
// Framework PriceInfoInterface - has getPrice() method, returned by Product::getPriceInfo()
112+
$this->frameworkPriceInfoMock = $this->createMock(FrameworkPriceInfoInterface::class);
94113

95114
$this->model = new Tax(
96115
$this->priceCurrencyMock,
@@ -101,79 +120,119 @@ protected function setUp(): void
101120
}
102121

103122
/**
123+
* Test collect method
124+
*
104125
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
105126
*/
106127
public function testCollect(): void
107128
{
108-
$this->markTestSkipped(
109-
'Test requires mocking getPrice() method which does not exist in PriceInfoInterface. ' .
110-
'PHPUnit 12 removed addMethods() and getMockForAbstractClass() methods, ' .
111-
'making it impossible to mock non-existent methods without test refactoring. ' .
112-
'This test needs to be refactored to mock a concrete implementation that has getPrice() method.'
113-
);
114-
115129
$amountValue = 10;
116130
$minAmountValue = 5;
117131
$storeId = 1;
118132
$currencyCode = 'usd';
119133

120134
$productMock = $this->createMock(Product::class);
121135
$productRender = $this->createMock(ProductRenderInterface::class);
122-
$price = $this->createMock(FinalPrice::class);
123-
// PriceInfoInterface: Using the mock already created in setUp() instead of creating a new one
124-
// This avoids the issue of mocking getPrice() which doesn't exist in the interface
125-
$priceInfo = $this->priceMock;
136+
$finalPrice = $this->createMock(FinalPrice::class);
137+
$regularPrice = $this->createMock(FinalPrice::class);
126138
$amount = $this->createMock(AmountInterface::class);
127139
$minAmount = $this->createMock(AmountInterface::class);
140+
$maxAmount = $this->createMock(AmountInterface::class);
128141

129-
$priceInfo->expects($this->exactly(4))
130-
->method('getPrice')
131-
->willReturn($price);
132-
$this->priceInfoFactory->expects($this->once())
133-
->method('create')
134-
->willReturn($priceInfo);
135-
$productRender->expects($this->once())
136-
->method('getPriceInfo')
137-
->willReturn($priceInfo);
142+
// Product::getPriceInfo() returns Framework's PriceInfoInterface (has getPrice())
138143
$productMock->expects($this->any())
139144
->method('getPriceInfo')
140-
->willReturn($priceInfo);
141-
$priceInfo->expects($this->once())
142-
->method('getExtensionAttributes')
143-
->willReturn($this->extensionAttributes);
144-
$priceInfo->expects($this->atLeastOnce())
145-
->method('getPrice')
146-
->willReturn($price);
147-
148-
$price->expects($this->once())
149-
->method('getMaximalPrice')
145+
->willReturn($this->frameworkPriceInfoMock);
146+
147+
// Framework PriceInfo's getPrice() returns price objects
148+
$this->frameworkPriceInfoMock->method('getPrice')
149+
->willReturnCallback(function ($priceCode) use ($finalPrice, $regularPrice) {
150+
if ($priceCode === 'final_price') {
151+
return $finalPrice;
152+
}
153+
if ($priceCode === 'regular_price') {
154+
return $regularPrice;
155+
}
156+
return $finalPrice;
157+
});
158+
159+
// Setup price amounts
160+
$finalPrice->expects($this->atLeastOnce())
161+
->method('getAmount')
150162
->willReturn($amount);
151-
$price->expects($this->once())
163+
$finalPrice->expects($this->once())
164+
->method('getMaximalPrice')
165+
->willReturn($maxAmount);
166+
$finalPrice->expects($this->once())
152167
->method('getMinimalPrice')
153168
->willReturn($minAmount);
154-
$price->expects($this->exactly(2))
169+
170+
$regularPrice->expects($this->once())
155171
->method('getAmount')
156172
->willReturn($amount);
157-
$amount->expects($this->exactly(3))
173+
174+
$amount->expects($this->atLeastOnce())
158175
->method('getValue')
176+
->with(['tax', 'weee'])
159177
->willReturn($amountValue);
178+
179+
$maxAmount->expects($this->once())
180+
->method('getValue')
181+
->with(['tax', 'weee'])
182+
->willReturn($amountValue);
183+
160184
$minAmount->expects($this->once())
161185
->method('getValue')
186+
->with(['tax', 'weee'])
162187
->willReturn($minAmountValue);
188+
189+
// ProductRender::getPriceInfo() returns Catalog API's PriceInfoInterface (DTO)
190+
$productRender->expects($this->once())
191+
->method('getPriceInfo')
192+
->willReturn($this->renderPriceInfoMock);
193+
194+
// PriceInfo factory creates new PriceInfo DTOs
195+
$newPriceInfo = $this->createMock(PriceInfoInterface::class);
196+
$this->priceInfoFactory->expects($this->once())
197+
->method('create')
198+
->willReturn($newPriceInfo);
199+
200+
// Setup extension attributes
201+
$this->renderPriceInfoMock->expects($this->once())
202+
->method('getExtensionAttributes')
203+
->willReturn($this->extensionAttributes);
204+
205+
// Extension attributes setTaxAdjustments is called
206+
$this->extensionAttributes->expects($this->once())
207+
->method('setTaxAdjustments')
208+
->with($newPriceInfo);
209+
210+
// Setup price info setters on new DTO
211+
$newPriceInfo->expects($this->once())->method('setFinalPrice')->with($amountValue);
212+
$newPriceInfo->expects($this->once())->method('setMaxPrice')->with($amountValue);
213+
$newPriceInfo->expects($this->once())->method('setMinimalPrice')->with($minAmountValue);
214+
$newPriceInfo->expects($this->once())->method('setSpecialPrice');
215+
$newPriceInfo->expects($this->once())->method('setRegularPrice')->with($amountValue);
216+
$newPriceInfo->method('getFinalPrice')->willReturn($amountValue);
217+
218+
$this->renderPriceInfoMock->expects($this->once())
219+
->method('setExtensionAttributes')
220+
->with($this->extensionAttributes);
221+
163222
$productRender->expects($this->once())
164223
->method('setPriceInfo')
165-
->with($priceInfo);
224+
->with($this->renderPriceInfoMock);
166225

167226
$productRender->expects($this->once())
168227
->method('getStoreId')
169-
->willReturn(1);
228+
->willReturn($storeId);
170229
$productRender->expects($this->once())
171230
->method('getCurrencyCode')
172231
->willReturn($currencyCode);
173232

174233
$this->formattedPriceInfoBuilder->expects($this->once())
175234
->method('build')
176-
->with($priceInfo, $storeId, $currencyCode);
235+
->with($newPriceInfo, $storeId, $currencyCode);
177236

178237
$this->model->collect($productMock, $productRender);
179238
}

0 commit comments

Comments
 (0)