RevertQuoteInventoryObserverTest::testExecute()   A
last analyzed

Complexity

Conditions 3
Paths 4

Size

Total Lines 52

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 37
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
nc 4
nop 0
dl 0
loc 52
ccs 37
cts 37
cp 1
crap 3
rs 9.0472
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
4
namespace Stockbase\Integration\Test\Unit\Model\Observer;
5
6
use Magento\CatalogInventory\Observer\ProductQty;
7
use Magento\CatalogInventory\Api\StockManagementInterface;
8
use Magento\CatalogInventory\Model\Indexer\Stock\Processor as IndexStockProcessor;
9
use Magento\Catalog\Model\Indexer\Product\Price\Processor as ProductPriceProcessor;
10
use Magento\Framework\TestFramework\Unit\Matcher\MethodInvokedAtIndex;
11
use PHPUnit\Framework\TestCase;
12
use Stockbase\Integration\Model\Inventory\StockbaseStockManagement;
13
use Stockbase\Integration\Model\Observer\RevertQuoteInventoryObserver;
14
use Stockbase\Integration\Model\StockItemReserve;
15
16
/**
17
 * Class RevertQuoteInventoryObserverTest
18
 */
19
class RevertQuoteInventoryObserverTest extends TestCase
20
{
21
    const TEST_WEBSITE_ID = 0xdeadbeef;
22
    
23
    /** @var ProductQty|\PHPUnit_Framework_MockObject_MockObject */
24
    private $productQty;
25
26
    /** @var StockManagementInterface|\PHPUnit_Framework_MockObject_MockObject */
27
    private $stockManagement;
28
29
    /** @var IndexStockProcessor|\PHPUnit_Framework_MockObject_MockObject */
30
    private $stockIndexerProcessor;
31
32
    /** @var ProductPriceProcessor|\PHPUnit_Framework_MockObject_MockObject */
33
    private $priceIndexer;
34
35
    /** @var StockbaseStockManagement|\PHPUnit_Framework_MockObject_MockObject */
36
    private $stockbaseStockManagement;
37
38
    /** @var \Magento\Quote\Model\Quote|\PHPUnit_Framework_MockObject_MockObject */
39
    private $quote;
40
41
    /** @var \Magento\Framework\Event\Observer */
42
    private $observer;
43
44
    /**
45
     * {@inheritdoc}
46
     */
47 3
    public function setUp()
48
    {
49 3
        $this->productQty = $this->createMock(ProductQty::class);
50
        
51 3
        $this->stockManagement = $this->getMockBuilder(\Magento\CatalogInventory\Model\StockManagement::class)
52 3
            ->disableOriginalConstructor()
53 3
            ->setMethods(['revertProductsSale'])
54 3
            ->getMock();
55
        
56 3
        $this->stockIndexerProcessor = $this->createMock(IndexStockProcessor::class);
57
        
58 3
        $this->priceIndexer = $this->createMock(ProductPriceProcessor::class);
59
        
60 3
        $this->stockbaseStockManagement = $this->createMock(StockbaseStockManagement::class);
61
62 3
        $this->quote = $this->getMockBuilder(\Magento\Quote\Model\Quote::class)
63 3
            ->disableOriginalConstructor()
64 3
            ->setMethods([
65 3
                'getInventoryProcessed',
66
                'setInventoryProcessed',
67
                'getAllItems',
68
                'getStore',
69
            ])
70 3
            ->getMock();
71
72 3
        $store = $this->createMock(\Magento\Store\Api\Data\StoreInterface::class);
73 3
        $store->method('getWebsiteId')->willReturn(self::TEST_WEBSITE_ID);
74
75 3
        $this->quote->method('getStore')->willReturn($store);
76
        
77 3
        $this->observer = new \Magento\Framework\Event\Observer([
78 3
            'event' => new \Magento\Framework\Event([
79 3
                'quote' => $this->quote,
80
            ]),
81
        ]);
82 3
    }
83
84
    /**
85
     * testExecute
86
     * @dataProvider itemsProvider
87
     */
88 3
    public function testExecute()
89
    {
90 3
        $itemPrototypes = func_get_args();
91
        
92 3
        $items = [];
93 3
        $magentoReserve = [];
94 3
        foreach ($itemPrototypes as $index => $itemPrototype) {
95 2
            $item = $this->getMockBuilder(\Magento\Quote\Model\Quote\Item::class)
96 2
                ->disableOriginalConstructor()
97 2
                ->setMethods(['getProductId', 'getChildrenItems', 'getTotalQty', 'getId'])
98 2
                ->getMock();
99
100 2
            $item->method('getId')->willReturn($itemPrototype['id']);
101 2
            $item->method('getProductId')->willReturn($itemPrototype['productId']);
102 2
            $item->method('getChildrenItems')->willReturn([]);
103 2
            $item->method('getTotalQty')->willReturn($itemPrototype['requestedQty']);
104
105 2
            $items[$index] = $item;
106 2
            $magentoReserve[$itemPrototype['productId']] = $itemPrototype['magentoReserve'];
107
108 2
            $reserveItem = $this->createMock(StockItemReserve::class);
109 2
            $reserveItem->method('getEan')->willReturn($itemPrototype['productId']);
110 2
            $reserveItem->method('getAmount')->willReturn($itemPrototype['stockbaseReserve']);
111 2
            $reserveItem->method('getMagentoStockAmount')->willReturn($itemPrototype['magentoReserve']);
112
113 2
            $this->stockbaseStockManagement->expects(new MethodInvokedAtIndex($index))->method('getReserveForQuoteItem')
0 ignored issues
show
Bug introduced by
The method expects does only exist in PHPUnit_Framework_MockObject_MockObject, but not in Stockbase\Integration\Mo...tockbaseStockManagement.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
114 2
                ->with($itemPrototype['id'])
115 2
                ->willReturn([$reserveItem]);
116
117 2
            $this->stockbaseStockManagement->expects(new MethodInvokedAtIndex($index))->method('releaseReserve')
118 2
                ->with($reserveItem);
119
        }
120
        
121 3
        $this->quote->method('getAllItems')->willReturn($items);
122
        
123 3
        $this->stockManagement->expects($this->once())->method('revertProductsSale')
124 3
            ->with($magentoReserve, self::TEST_WEBSITE_ID);
125
        
126 3
        $productIds = array_keys($magentoReserve);
127 3
        if (!empty($productIds)) {
128 2
            $this->stockIndexerProcessor->expects($this->once())->method('reindexList')->with($productIds);
129 2
            $this->priceIndexer->expects($this->once())->method('reindexList')->with($productIds);
130
        } else {
131 1
            $this->stockIndexerProcessor->expects($this->never())->method('reindexList');
132 1
            $this->priceIndexer->expects($this->never())->method('reindexList');
133
        }
134
        
135 3
        $this->quote->expects($this->once())->method('setInventoryProcessed')->with(false);
136
137 3
        $handler = $this->createHandler();
138 3
        $handler->execute($this->observer);
139 3
    }
140
141
    /**
142
     * @return array
143
     */
144
    public function itemsProvider()
145
    {
146
        return [
147
            [
148
                [
149
                    'id' => 201,
150
                    'productId' => 101,
151
                    'requestedQty' => 5,
152
                    'magentoReserve' => 3,
153
                    'stockbaseReserve' => 2,
154
                ],
155
                [
156
                    'id' => 202,
157
                    'productId' => 102,
158
                    'requestedQty' => 3,
159
                    'magentoReserve' => 0,
160
                    'stockbaseReserve' => 3,
161
                ],
162
            ],
163
            [
164
                [
165
                    'id' => 201,
166
                    'productId' => 101,
167
                    'requestedQty' => 6,
168
                    'magentoReserve' => 6,
169
                    'stockbaseReserve' => 0,
170
                ],
171
            ],
172
            [],
173
        ];
174
    }
175
176 3
    protected function createHandler()
177
    {
178 3
        return new RevertQuoteInventoryObserver(
179 3
            $this->productQty,
180 3
            $this->stockManagement,
181 3
            $this->stockIndexerProcessor,
182 3
            $this->priceIndexer,
183 3
            $this->stockbaseStockManagement
184
        );
185
    }
186
}
187