Test Laravel AI Systems with Zero API Calls | Mohamed Said        [  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png)   Mohamed Said Laravel Backend Engineer  ](https://www.msaied.com) [ Home ](https://www.msaied.com) [ Projects ](https://www.msaied.com/projects) [ Articles  ](https://www.msaied.com/articles) [ Certificates ](https://www.msaied.com/certificates) [ Contact ](https://www.msaied.com#contact-section) 

       [  ](https://github.com/EG-Mohamed)       

 [ Home ](https://www.msaied.com) [ Projects ](https://www.msaied.com/projects) [ Articles ](https://www.msaied.com/articles) [ Certificates ](https://www.msaied.com/certificates) [ Contact ](https://www.msaied.com#contact-section) 

  [ home ](https://www.msaied.com)    [ articles ](https://www.msaied.com/articles)    Ship AI with Laravel: Test Your AI System with Zero API Calls        On this page       1. [  The Problem with Testing AI Code ](#the-problem-with-testing-ai-code)
2. [  Setting Up the Fake ](#setting-up-the-fake)
3. [  What Gets Tested ](#what-gets-tested)
4. [  Agent Prompting and Conversation Context ](#agent-prompting-and-conversation-context)
5. [  Preventing Accidental AI Calls ](#preventing-accidental-ai-calls)
6. [  Queued Prompts ](#queued-prompts)
7. [  Custom Tools Against Real Database Records ](#custom-tools-against-real-database-records)
8. [  Feature Testing the Chat Endpoint ](#feature-testing-the-chat-endpoint)
9. [  Vector Store and Knowledge Base ](#vector-store-and-knowledge-base)
10. [  The Result ](#the-result)
11. [  Key Takeaways ](#key-takeaways)
12. [  What's Next ](#whats-next)

  ![Ship AI with Laravel: Test Your AI System with Zero API Calls](https://cdn.msaied.com/331/52e9e0988d8c9a6dc40174a7c6256301.png)

 [  Laravel ](https://www.msaied.com/articles?category=laravel) [  AI ](https://www.msaied.com/articles?category=ai)  #Laravel   #AI Testing   #Pest   #PHP   #OpenAI   #TDD  

 Ship AI with Laravel: Test Your AI System with Zero API Calls 
===============================================================

     27 Jun 2026      3 min read    ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said  

       Table of contents

  12 sections  

1. [  01   The Problem with Testing AI Code  ](#the-problem-with-testing-ai-code)
2. [  02   Setting Up the Fake  ](#setting-up-the-fake)
3. [  03   What Gets Tested  ](#what-gets-tested)
4. [  04   Agent Prompting and Conversation Context  ](#agent-prompting-and-conversation-context)
5. [  05   Preventing Accidental AI Calls  ](#preventing-accidental-ai-calls)
6. [  06   Queued Prompts  ](#queued-prompts)
7. [  07   Custom Tools Against Real Database Records  ](#custom-tools-against-real-database-records)
8. [  08   Feature Testing the Chat Endpoint  ](#feature-testing-the-chat-endpoint)
9. [  09   Vector Store and Knowledge Base  ](#vector-store-and-knowledge-base)
10. [  10   The Result  ](#the-result)
11. [  11   Key Takeaways  ](#key-takeaways)
12. [  12   What's Next  ](#whats-next)

       The Problem with Testing AI Code
--------------------------------

Testing code that calls an external AI API is painful. Hitting OpenAI in your test suite is slow, costs money on every run, and returns non-deterministic responses — making stable assertions nearly impossible. If you've been skipping AI tests for these reasons, this episode of the *Ship AI with Laravel* series shows you a better path.

Using **Pest** and the Laravel AI SDK's built-in faking system, you can test your entire AI platform without a single real API call. The pattern mirrors how Laravel already handles faking mail, notifications, and queues — define responses up front, then assert the right prompts went out.

Setting Up the Fake
-------------------

The SDK's faking system lets you swap out real AI calls with pre-defined responses in your test setup. This gives you deterministic output every time:

```php
use Prism\Prism;

Prism::fake([
    'This ticket is about a billing issue.',
]);

```

With the fake in place, your agent, tools, and middleware all execute their real logic — only the external HTTP call is intercepted.

What Gets Tested
----------------

### Agent Prompting and Conversation Context

The first set of tests verifies that the agent receives the correct prompt and that conversation history is passed through properly. Because responses are fixed, assertions on the returned content are stable across every run.

### Preventing Accidental AI Calls

`preventStrayPrompts()` is a safety net that causes a test to fail if an AI call fires in a flow that should never trigger the agent — for example, during basic ticket creation:

```php
Prism::preventStrayPrompts();

// Any unexpected AI call in this flow will now throw
$this->post('/tickets', $payload);

```

This catches regressions where a refactor accidentally introduces an AI call where none was intended.

### Queued Prompts

For background classification jobs, you can assert that a queued prompt is dispatched on a valid submission and stays out of the queue on an invalid one:

```php
Queue::fake();

$this->post('/tickets', $validPayload);

Queue::assertPushed(TicketClassifier::class);

```

### Custom Tools Against Real Database Records

Custom tools are tested directly against real database records seeded in the test. A failing test in this episode caught a factory mismatch live — exactly the kind of regression a test suite is supposed to surface.

### Feature Testing the Chat Endpoint

The chat endpoint is covered for authentication, request validation, and correct agent interaction, all without touching OpenAI.

### Vector Store and Knowledge Base

Store creation, document uploads, and embedding generation are all faked, letting you assert the full knowledge-base seeding flow without any external calls.

The Result
----------

All **12 AI tests pass**, run in seconds, and never touch an external API. You can run them on every commit without worrying about cost or flakiness.

### Key Takeaways

- The Laravel AI SDK ships a faking system that works just like `Mail::fake()` or `Queue::fake()`.
- `preventStrayPrompts()` guards flows that should never trigger an AI call.
- Queued AI jobs can be asserted with `Queue::fake()` the same way as any other job.
- Custom tools should be tested against real seeded records to catch factory mismatches early.
- Feature tests cover auth, validation, and agent interaction without any API cost.
- Deterministic faked responses make assertions reliable across every CI run.

What's Next
-----------

The next episode moves into security — protecting the agent against prompt injection by screening every incoming message with a local LLM before it reaches OpenAI, with zero API cost on blocked requests.

📺 [Watch Episode 10 on YouTube](https://youtu.be/r1F-fxVeehA) | ⭐ [GitHub Repository](https://github.com/harris21/ship-ai-with-laravel)

---

*Source: [Laravel News — Ship AI with Laravel: Test Your AI System with Zero API Calls](https://laravel-news.com/ship-ai-with-laravel-test-your-ai-system-with-zero-api-calls)*

 Found this useful?

          [  ](https://twitter.com/intent/tweet?url=https%3A%2F%2Fwww.msaied.com%2Farticles%2Fship-ai-with-laravel-test-your-ai-system-with-zero-api-calls&text=Ship+AI+with+Laravel%3A+Test+Your+AI+System+with+Zero+API+Calls) [  ](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fwww.msaied.com%2Farticles%2Fship-ai-with-laravel-test-your-ai-system-with-zero-api-calls) 

 Frequently Asked Questions 
----------------------------

  3 questions  

     Q01  How do you fake AI API calls in Laravel tests?        The Laravel AI SDK provides a faking system similar to `Mail::fake()` or `Queue::fake()`. You call `Prism::fake([...])` with an array of pre-defined responses before your test runs. The agent and tools execute their real logic, but no HTTP request is made to OpenAI or any other provider. 

      Q02  What does preventStrayPrompts() do in Laravel AI tests?        `preventStrayPrompts()` causes a test to fail immediately if an AI prompt fires in a code path where none is expected. It acts as a regression guard — if a refactor accidentally introduces an AI call into a flow like basic ticket creation, the test suite will catch it. 

      Q03  Can queued AI classification jobs be tested without real API calls?        Yes. Combine `Queue::fake()` with `Prism::fake()` to assert that a job such as `TicketClassifier` is pushed onto the queue for valid input and not pushed for invalid input, all without dispatching real jobs or making API calls. 

  Continue reading

 More Articles 
---------------

 [ View all    ](https://www.msaied.com/articles) 

 [ ![Filament v5 Preview: Schema Unification, Performance Shifts, and How to Prepare](https://cdn.msaied.com/340/1a05ca68637b898b676efb66f22e627f.png) filament laravel php 

### Filament v5 Preview: Schema Unification, Performance Shifts, and How to Prepare

Filament v5 is reshaping how panels, forms, and tables are composed. This deep-dive covers the confirmed archi...

  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said 

 1 Jul 2026     4 min read  

  Read    

 ](https://www.msaied.com/articles/filament-v5-preview-schema-unification-performance-shifts-and-how-to-prepare) [ ![Laravel 13: New Features, Helpers, and Practical Upgrade Notes](https://cdn.msaied.com/339/58c4fa6fe9b6d25a2dac17c621b6f4c6.png) laravel laravel-13 upgrade 

### Laravel 13: New Features, Helpers, and Practical Upgrade Notes

Laravel 13 ships with async-first defaults, a leaner bootstrapping layer, and several quality-of-life helpers....

  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said 

 1 Jul 2026     3 min read  

  Read    

 ](https://www.msaied.com/articles/laravel-13-new-features-helpers-and-practical-upgrade-notes) [ ![Laravel 12: Structured Route Files, Slim Skeletons, and the New Application Bootstrapping](https://cdn.msaied.com/337/05b39d16d0f88a5fb94d0cf74049b88b.png) laravel laravel-12 upgrade 

### Laravel 12: Structured Route Files, Slim Skeletons, and the New Application Bootstrapping

Laravel 12 ships with a leaner skeleton, first-class route file organisation, and a revised application bootst...

  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said 

 1 Jul 2026     3 min read  

  Read    

 ](https://www.msaied.com/articles/laravel-12-structured-route-files-slim-skeletons-and-the-new-application-bootstrapping) 

   [  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png)   Mohamed Said Laravel Backend Engineer  ](https://www.msaied.com)Senior Backend Engineer specializing in Laravel, scalable SaaS platforms, APIs, and cloud infrastructure. I build secure, high-performance web applications that help businesses grow.

Explore

- [Home](https://www.msaied.com)
- [Projects](https://www.msaied.com/projects)
- [Articles](https://www.msaied.com/articles)
- [Certificates](https://www.msaied.com/certificates)
- [Contact](https://www.msaied.com#contact-section)

Connect

- [   hello@msaied.com ](mailto:hello@msaied.com)
- [   +20 109 461 9204 ](tel:+201094619204)

© 2026 Mohamed Said. All rights reserved.

 [  ](https://github.com/EG-Mohamed) [  ](https://www.linkedin.com/in/msaiedm/) [  ](https://wa.me/201094619204) [  ](mailto:hello@msaied.com) [  ](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)
