flyingL123

Experience

10,830

0 Best Reply Awards

  • Member Since 6 Months Ago
  • 107 Lessons Completed
  • 2 Favorites

12th June, 2018

flyingL123 left a reply on Creating And Dropping A Table During Test Breaks RefreshDatabase Trait • 1 week ago

Making the stubs table temporary did the trick. Creating a table causes an implicit commit in mysql. Creating a temporary table does not. It also means I don't need to drop the table either, since it happens automatically:

Schema::create('stubs', function ($table) {
    $table->temporary()
    $table->increments('id');
    $table->string('name');
    $table->timestamps();
});

Seems to be working perfectly so far.

flyingL123 started a new conversation Creating And Dropping A Table During Test Breaks RefreshDatabase Trait • 1 week ago

I've created a trait using in my Laravel 5.6 app. The trait is called Projectable. This trait is meant to be used by Eloquent models. In order to test the trait, I wanted to create a ProjectableStub model to use in the tests. However, since this is an Eloquent model, it requires a table.

I wanted to simply create and drop a table just for testing. However, when I do this, it seems like something breaks regarding the RefreshDatabase functionality. To demonstrate, I am simply running two tests, both of which try to create a Product model with id = 1. Since the RefreshDatabase trait is being used, this should work fine. And, in the example below, it does:

    <?php
    
    namespace Tests\Feature;
    
    use App\Product;
    use Tests\TestCase;
    use App\Concerns\Projectable;
    use Illuminate\Support\Facades\Schema;
    use Illuminate\Foundation\Testing\WithFaker;
    use Illuminate\Foundation\Testing\RefreshDatabase;
    use Illuminate\Database\Eloquent\Model as Eloquent;
    
    class ProjectableTest extends TestCase
    {
        use RefreshDatabase;
    
        public function setUp()
        {
            parent::setUp();
    
            //$this->createStubTable();
        }
    
        /**
         * @test
         */
        public function example_first_test()
        {
            factory(Product::class)->create(['id' => 1]);
        }
    
        /**
         * @test
         */
        public function example_second_test()
        {
            factory(Product::class)->create(['id' => 1]);
        }
    
        public function tearDown()
        {
            //$this->dropStubTable();
    
            parent::tearDown();
        }
    
        private function createStubTable()
        {
            Schema::create('stubs', function ($table) {
                $table->increments('id');
                $table->string('name');
                $table->timestamps();
            });
        }
    
        private function dropStubTable()
        {
            Schema::dropIfExists('stubs');
        }
    }

    class ProjectableStub extends Eloquent
    {
        use Projectable;
    
        protected $table = 'stubs';
    
        protected $guarded = [];
    }

However, as soon as I uncomment the two lines so that the stubs table is created and dropped, I get a SQL error that a duplicate ID is being used:

    <?php
    
    namespace Tests\Feature;
    
    use App\Product;
    use Tests\TestCase;
    use App\Concerns\Projectable;
    use Illuminate\Support\Facades\Schema;
    use Illuminate\Foundation\Testing\WithFaker;
    use Illuminate\Foundation\Testing\RefreshDatabase;
    use Illuminate\Database\Eloquent\Model as Eloquent;
    
    class ProjectableTest extends TestCase
    {
        use RefreshDatabase;
    
        public function setUp()
        {
            parent::setUp();
    
            $this->createStubTable();
        }
    
        /**
         * @test
         */
        public function example_first_test()
        {
            factory(Product::class)->create(['id' => 1]);
        }
    
        /**
         * @test
         */
        public function example_second_test()
        {
            factory(Product::class)->create(['id' => 1]);
        }
    
        public function tearDown()
        {
            $this->dropStubTable();
    
            parent::tearDown();
        }
    
        private function createStubTable()
        {
            Schema::create('stubs', function ($table) {
                $table->increments('id');
                $table->string('name');
                $table->timestamps();
            });
        }
    
        private function dropStubTable()
        {
            Schema::dropIfExists('stubs');
        }
    }

    class ProjectableStub extends Eloquent
    {
        use Projectable;
    
        protected $table = 'stubs';
    
        protected $guarded = [];
    }
  1. Tests\Feature\ProjectableTest::example_second_test Illuminate\Database\QueryException: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '1' for key 'PRIMARY'

Does anyone know why creating and dropping a table within the test is causing this issue? Is there a better way to go about this? Maybe some way to add a migration at runtime for this new table?

12th March, 2018

flyingL123 left a reply on Best Practice For Developing A Site That Uses 3rd Party APIs • 3 months ago

I just found this which seems to be getting at what I'm asking:

http://www.culttt.com/2015/08/31/how-to-resolve-environment-specific-implementations-from-laravels-ioc-container/

Hopefully this will get me started.

flyingL123 left a reply on Best Practice For Developing A Site That Uses 3rd Party APIs • 3 months ago

@shez1983 I guess what I'm trying to say is that there isn't actually any real data to fetch because I'm seeding the database with fake information. In production, objects in my database would correspond to real objects in BigCommerce, so the API calls will make sense and work, however, during development, making these API calls doesn't make sense because the corresponding objects don't exist in BigCommerce.

One option that makes sense to me would be to create a 'fake' BigCommerce class that just uses sub function to return fake data. I understand how to do this during tests, by creating mocks and binding to the container during the test or even in a setUp method.

But how would I do this same thing during development?

flyingL123 started a new conversation Best Practice For Developing A Site That Uses 3rd Party APIs • 3 months ago

What is the best way to handle developing an app that accesses 3rd-party apis? For example, I have an app that relies on data from the BigCommerce API. Every time a certain route is loaded, a call is made to using a 3rd party BigCommerce library to hit their API. For example,

public function view(Store $store)
{
    $bcStore = Bigcommerce::getStore($store->id);

    // Do some stuff with the data before returning the view

    return view('stores.view');
}

As I am developing this app I am obviously loading this route many times in a browser, which means I'm making an continuously hitting the BigCommerce servers. Additionally, the data I seed my database with for developing is not for real BigCommerce stores, so these continuous calls to the BigCommerce server are all going to fail.

What is the best practice for this sort of situation? During testing I know I can create mocks and use the Service Container to bind the mocks rather than the real classes. Am I supposed to do the same thing for development? If so, where and how do I do this?

Just trying to understand what my options are. This seems like a pretty common thing but I'm struggling to figure out the "right" way to handle it.

Edit Your Profile
Update

Want to change your profile photo? We pull from gravatar.com.