Test Failed
Push — main ( 99efcd...df6632 )
by Alex
14:53
created

HandleUseTest::testProcessActionUseItemOnlyInInventory()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 56
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 1
eloc 34
c 2
b 0
f 0
nc 1
nop 0
dl 0
loc 56
rs 9.376

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
namespace App\Tests\Adventure;
4
5
use App\Adventure\Game;
6
use App\Adventure\Location;
7
use App\Adventure\Inventory;
8
use App\Adventure\Item;
9
use App\Adventure\InputActions\UseAction;
10
use App\Adventure\ActionResponses\MoveLocationResponse;
11
use PHPUnit\Framework\TestCase;
12
13
/**
14
 * Unit tests for Game class. Specifically testing 'use' action.
15
 */
16
class HandleUseTest extends TestCase
17
{
18
    /**
19
     * @var Game
20
     */
21
    private $game;
22
23
    protected function setUp(): void
24
    {
25
        $this->game = new Game();
26
    }
27
28
    /**
29
     * Test case for processAction method with 'use' with item in inventory.
30
     */
31
    public function testProcessActionUseItemOnlyInInventory(): void
32
    {
33
        // Stub a location to start in
34
        $startingLocation = $this->createStub(Location::class);
35
36
        // Create a mock location to move to
37
        $responseLocation = $this->createMock(Location::class);
38
        $responseLocation->expects($this->once())
39
            ->method('getLocationDetails')
40
            ->willReturn('A testy test location.');
41
42
        // Create and configure a response mock
43
        $response = $this->createMock(MoveLocationResponse::class);
44
        $response->expects($this->once())
45
            ->method('doLocationResponse')
46
            ->with($startingLocation)
47
            ->willReturn($responseLocation);
48
49
        // Create and configure use action mock
50
        $action = $this->createMock(UseAction::class);
51
        $action->method('getTextResponse')->willReturn('You use the key.');
52
        $action->method('getLocationResponse')->willReturn($response);
53
54
        // Create and configure item mock
55
        $item = $this->createMock(Item::class);
56
        $item->method('hasAction')->with('use')->willReturn(true);
57
        $item->method('getAction')->with('use')->willReturn($action);
58
        $item->method('getName')->willReturn('key');
59
60
        // Configure inventory mock to find the item
61
        $inventory = $this->createMock(Inventory::class);
62
        $inventory->expects($this->once())
63
            ->method('getItem')
64
            ->with('key')
65
            ->willReturn($item);
66
67
        $inventory->expects($this->exactly(2))
68
            ->method('hasItem')
69
            ->with('key')
70
            ->willReturn(true);
71
72
        // Expect item to be removed after use
73
        $inventory->expects($this->once())
74
            ->method('removeItem')
75
            ->with($item);
76
77
        // Perform action
78
        $this->game->setInventory($inventory);
79
        $this->game->setCurrentLocation($startingLocation);
80
        $response = $this->game->processAction('use', 'key');
81
82
        // Assert use message is returned with the resuling locations details
83
        $this->assertSame("You use the key.\n\nA change has occurred. Behold, the updated location awaits:\nA testy test location.\n", $response);
84
85
        // Also, assert location is changed
86
        $this->assertSame($responseLocation, $this->game->getCurrentLocation());
87
    }
88
89
    /**
90
     * Test case for processAction method with 'use' with item not in inventory.
91
     */
92
    public function testProcessActionUseItemNotInInventory(): void
93
    {
94
        // Create and configure use action mock
95
        $action = $this->createMock(UseAction::class);
96
        $action->method('getTextResponse')->willReturn('You use the key.');
97
98
        // Create and configure item mock
99
        $item = $this->createMock(Item::class);
100
        $item->method('hasAction')->with('use')->willReturn(true);
101
        $item->method('getAction')->with('use')->willReturn($action);
102
        $item->method('getName')->willReturn('key');
103
104
        // Configure location mock to find the item
105
        $location = $this->createMock(Location::class);
106
        $location->expects($this->once())
107
            ->method('hasItem')
108
            ->with('key')
109
            ->willReturn(true);
110
111
        $location->expects($this->once())
112
            ->method('getItem')
113
            ->with('key')
114
            ->willReturn($item);
115
116
        // Configure inventory to NOT have the item
117
        $inventory = $this->createMock(Inventory::class);
118
        $inventory->method('hasItem')
119
            ->with('key')
120
            ->willReturn(false);
121
122
        // Expect item to NOT get removed
123
        $inventory->expects($this->never())
124
            ->method('removeItem');
125
126
        // Perform action
127
        $this->game->setCurrentLocation($location);
128
        $this->game->setInventory($inventory);
129
        $response = $this->game->processAction('use', 'key');
130
131
        // Assert error message is returned
132
        $this->assertSame('Make sure you have the key before attempting to use it.', $response);
133
    }
134
}
135