create a new service class for file_get_contents(self::URL . $season) and inject it in your command, then mock the service when you write tests
Jun 3, 2022
1
Level 3
How would you test a command like this?
Hi all, I have some experience in writing tests, but most of them are HTTP testing and expected data are easily mocked using factories. I'm just wondering how you guys would test a command like below? I'm not really expecting you guys to write the code, but more so give advice and tips. Maybe writing the command in another way that's easier to test etc. Is it even worth testing something like this when the site you're scraping is prone to changes etc?
What I'm currently thinking:
- Add a URL command arg so I can manually input a URL during the test.
- Add a test command arg so I can run the command differently when it's set to true. I can create test
jsonfile somewhere in my repo and use that as the mocked data.
PS - happy for you guys to critique the code, always happy to learn and improve.
<?php
namespace App\Console\Commands;
use App\Models\Round;
use Illuminate\Console\Command;
use Carbon\Carbon;
class ImportRoundData extends Command
{
protected $signature = 'import:round_data';
protected $description = 'Import round data. Round number, start and end times. Souce: fixturedownload.com';
protected const URL = 'https://fixturedownload.com/feed/json/afl-';
public function handle()
{
$season = config('gameplay.season');
$fixtures = json_decode(file_get_contents(self::URL . $season), true);
$rounds = [];
foreach($fixtures as $fixture) {
$rounds[$fixture['RoundNumber']][$fixture['MatchNumber']] = ['date' => (Carbon::parse($fixture['DateUtc']))->setTimezone('Australia/Melbourne')];
}
foreach ($rounds as $round => $roundData) {
$firstMatch = $roundData[array_key_first($roundData)];
$lastMatch = $roundData[array_key_last($roundData)];
Round::updateOrCreate(
['round' => $round, 'season' => $season],
['start_time' => ($firstMatch['date']), 'end_time' => ($lastMatch['date'])]
);
}
}
}
Thanks in advance.
Level 60
1 like
Please or to participate in this conversation.