rbur0425's avatar

Test Model From Job Class PHPUnit Mockery

How do I mock the markshipped method on the ebayOrders model? I am testing that the job handle() method works correctly. My current test the markshipped method still runs.

Job -

class ProcessOrderJob implements ShouldQueue
{
public function handle()
    {
        $DB = '';
        $Controller = '';
        if (strcmp($this->username, 'user1') === 0) {
            $DB = '\App\user1orders';
            
        } elseif (strcmp($this->username, 'user2') === 0) {
            $DB = '\App\user2orders';
            
        }

        while ($DB::all()->isNotEmpty()) {
            $order = $DB::first();

            $multiple_orders = $order->getOtherOrders();

            $processboxhelper = new ProcessBoxHelper();

            if ($multiple_orders->count() > 1) {
                $multiple_orders->push($order);

                if ($processboxhelper->process($multiple_orders)) {
                    $multiple_orders->map(function ($single_order) {
                        $response = $single_order->markShipped();
                        // $response = ['success' => true, 'ShippedTime' => now()];
                        if ($response['success']) {
                            $single_order->ShippedTime = $response['ShippedTime'];
                            $single_order->markComplete();
                        } else {
                            $single_order->markError();
                        }
                    });
                } else {
                    $multiple_orders->map(function ($single_order) {
                        $single_order->markError();
                    });
                }
            }


            if ($processboxhelper->process($order)) {
                $response = $order->markShipped();
                // $response = ['success' => true, 'ShippedTime' => now()];
                if ($response['success']) {
                    $order->ShippedTime = $response['ShippedTime'];
                    $order->markComplete();
                } else {
                    $order->markError();
                }
            } else {
                $order->markError();
            }
        }
    }
}

My test is currently -

class ProcessOrderJobTest extends TestCase
{
    use RefreshDatabase;
    /** @test */
    public function job_processes_order_successfully()
    {
        $order = factory(ebayOrders::class)->create();

        $order = $this->createMock(ebayOrders::class);
        $order->method('markShipped')
            ->willReturn(['success' => true, 'ShippedTime' => now()]);

        $job = new ProcessOrderJob(1, 'user1');
        $job->handle();

        $this->assertCount(1, CompletedOrder::all());
        $this->assertDatabaseHas('completed_orders', $order->toArray());
    }
}
0 likes
11 replies
bugsysha's avatar

Can you repeat what you are asking since I'm confused. Also why do you have factory created $order and mocked version of it assigned to the same variable?

rbur0425's avatar

I want to test the handle() method on my job class. In order for the handle method to run, it retrieves a record from the database and it performs a few methods on it. One of those methods is markShipped() which is what I want to mock as it uses a third party API to mark the order shipped.

bugsysha's avatar

Then you did all you need. Mock. Have it return successful result. And forget about it. Still not sure what you are asking, if I'm missing something.

rbur0425's avatar

When I run the test it fails. The mock doesn't get used, I am not sure why it does not get used. Could it be because the method is being called from the job class? The actual code in the markShipped method runs and it fails.

bugsysha's avatar

Are you sure it follows the correct path you are expecting since you have a bunch of if statements in your code?

rbur0425's avatar

Yes, it correctly goes to the method. Each if statement returns true or false.

bugsysha's avatar

Now I see the issue. So you are mocking that $order but that can not work that way. What are you using inside that markShipped method? Is it a Guzzle or something like that? If it is Guzzle then you have to mock that class and not the model object.

rbur0425's avatar

I am using ebay-php-sdk to build request to send to ebay. So I would mock the class inside the ebay-php-sdk that is making the request?

rbur0425's avatar

still not working. Is it because the mock is never directly used when the job class is instantiated and called?

class ProcessOrderJobTest extends TestCase
{
    use RefreshDatabase;
    /** @test */
    public function job_processes_order_successfully()
    {
        $test_order = factory(ebayOrders::class)->create();

        $response = '<?xml version="1.0" encoding="utf-8"?>
        <CompleteSaleResponse xmlns="urn:ebay:apis:eBLBaseComponents">
          <Ack>Success</Ack>
        </CompleteSaleResponse>';
        $mock = $this->createMock(\DTS\eBaySDK\Trading\Services\TradingService::class);
        $mock->method('completeSale')
            ->willReturn($response);

        $job = new ProcessOrderJob(1, 'user1');
        $job->handle();

        $this->assertCount(1, CompletedOrder::all());
        $this->assertDatabaseHas('completed_orders', $test_order->toArray());
    }
}
bugsysha's avatar

You are missing something. Without implementation details there is no way to help.

Please or to participate in this conversation.