Singleton

In laravel we usually use IoC to build our application, when we call one Class, all dependency in this class will involed.

For testing this class, we can defined depencency in service container as singleton.

Create a service provider:

php artisan make:provider WeatherServiceProvider

In here, using service container register a singleton for decoupling Prepare a singleton

WeatherServiceProvider.php

<?php

namespace App\Providers;

use App\Http\Services\WeatherServices;
use Illuminate\Support\ServiceProvider;

class WeatherServiceProvider extends ServiceProvider
{
    /**
     * Register services.
     *
     * @return void
     */
    public function register()
    {
        $this->app->singleton(WeatherServices::class, function($app) : weatherservices {
            return new WeatherServices('defalt from singleton');
        });
    }

    /**
     * Bootstrap services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }
}

Register your provider on config/app.php

    'providers' => [
        ...
        App\Providers\WeatherServiceProvider::class,]

Generate a test for service provider

Make sure the service perovider will call singleton, we make a unittest for this provider:

php artisan make:test WeatherServiceProviderTest

WeatherServiceProviderTest.php

<?php

namespace Tests\Feature;

use Tests\TestCase;
use App\Http\Services\WeatherServices;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;

class WeatherServiceProviderTest extends TestCase
{

    /**
     * A basic feature test example.
     *
     * @return void
     */
    public function testHasRegisterWeatherServiceProviderClassSingleton()
    {
        $this->assertTrue($this->app->bound(WeatherServices::class));
        $actual = $this->app->make(WeatherServices::class);
        $exptectd = $this->app->make(WeatherServices::class);
        $this->assertSame(
            $actual,
            $exptectd
        );
    }


    /**
     * A basic feature test example.
     *
     * @return void
     */
    public function testHasRegisterWeatherServiceShouldEqualAsSingleton()
    {
        $exptectd = new WeatherServices('defalt from singleton');
        $actual = $this->app->make(WeatherServices::class);
        $this->assertEquals(
            $exptectd,
            $actual
        );
    }
}

Create a route access weather controller

routes/api.php

Route::get('/hello', [WeatherController::class, 'currentWeather'] );

WeatherController.php

<?php

namespace App\Http\Controllers;

use Carbon\Carbon;
use Illuminate\Http\Request;
use App\Http\Services\WeatherServices;
use App\Exceptions\WeatherNotFoundException;

class weatherController extends Controller
{
    protected $users = 'default from controller';
    protected $WeatherServices;

    public function __construct(WeatherServices $WeatherServices)
    {
        $this->WeatherServices = $WeatherServices;
    }
    /**
     * current weather
     *
     * @return void
     */
    public function currentWeather($name = '')
    {
        if($name!=''){
            $this->users = $name;
        }
        try {
            $results = $this->WeatherServices->getWeather($this->users);
        } catch (WeatherNotFoundException $e) {
            report($e);
            return false;
        }
        return $results;
    }
}

WeatherServices.php

<?php

namespace App\Http\Services;

use Illuminate\Http\Request;
use App\Exceptions\WeatherNotFoundException;

class WeatherServices
{
    protected $users;
    public function __construct(string $users = '')
    {
        $this->users = $users;
    }

    /**
     * Get weather info
     *
     * @return array
     */
    public function getWeather($name='')
    {
        if ($name!='') {
            $this->users = $name;
        }

        if ($this->users == '') {
            throw new WeatherNotFoundException('please input user name');
        }

        return ['weather'=>'rain', 'user'=>$this->users];
    }
}