Testing
Test your components server-side without a browser using a fluent API.
Basic Usage
Use LiVue::test() to create a testable component instance:
use App\LiVue\Counter;
use LiVue\Facades\LiVue;
class CounterTest extends TestCase
{
public function test_counter_starts_at_zero()
{
LiVue::test(Counter::class)
->assertSet('count', 0);
}
public function test_counter_increments()
{
LiVue::test(Counter::class)
->call('increment')
->call('increment')
->assertSet('count', 2);
}
}
Interaction Methods
| Method | Description |
|---|---|
set('name', 'value') |
Simulate v-model update |
set(['name' => 'value']) |
Batch property updates |
call('method', $params) |
Call a component method |
toggle('property') |
Toggle a boolean property |
refresh() |
Re-render without changes |
dispatch('event', $data) |
Dispatch an event to listeners |
Assertions
Property Assertions
->assertSet('count', 5)
->assertSet('user.name', 'Mario') // dot notation
->assertNotSet('status', 'error')
->assertCount('items', 3)
HTML Assertions
->assertSee('Counter: 5')
->assertDontSee('Error')
->assertSeeHtml('<strong>5</strong>')
->assertSeeInOrder(['Step 1', 'Step 2', 'Step 3'])
Validation Assertions
->assertHasErrors() // any errors
->assertHasErrors('email') // specific field
->assertHasErrors(['name', 'email']) // multiple fields
->assertHasNoErrors()
->assertHasNoErrors(['name', 'email'])
Navigation Assertions
->assertRedirect() // any redirect
->assertRedirect('/dashboard') // specific URL
->assertNoRedirect()
->assertNavigate('/users/1') // SPA navigate
Event Assertions
->assertDispatched('form-saved')
->assertNotDispatched('error-occurred')
Full Example
class ContactFormTest extends TestCase
{
public function test_validates_required_fields()
{
LiVue::test(ContactForm::class)
->call('submit')
->assertHasErrors(['name', 'email', 'message']);
}
public function test_validates_email_format()
{
LiVue::test(ContactForm::class)
->set('name', 'Mario')
->set('email', 'invalid-email')
->set('message', 'Hello World')
->call('submit')
->assertHasErrors('email')
->assertHasNoErrors(['name', 'message']);
}
public function test_submits_valid_form()
{
LiVue::test(ContactForm::class)
->set([
'name' => 'Mario Rossi',
'email' => 'mario@example.com',
'message' => 'Hello World!',
])
->call('submit')
->assertHasNoErrors()
->assertDispatched('form-submitted')
->assertSee('Thank you!');
}
}
Testing with Mount Parameters
Pass parameters to the component's mount() method:
public function test_loads_user_on_mount()
{
$user = User::factory()->create(['name' => 'Mario Rossi']);
LiVue::test(UserProfile::class, ['userId' => $user->id])
->assertSet('user.name', 'Mario Rossi')
->assertSee('Mario Rossi');
}
Advanced Setup
// Test as authenticated user
LiVue::test(AdminPanel::class)
->actingAs($admin)
->assertSee('Admin Dashboard');
// Test with query parameters (#[Url])
LiVue::test(SearchPage::class)
->withQueryParams(['q' => 'laravel', 'page' => 2])
->assertSet('query', 'laravel')
->assertSet('page', 2);
// Test without lazy loading
LiVue::test(LazyWidget::class)
->withoutLazyLoading()
->assertSee('Widget Content');
Accessors
Access component internals for custom assertions:
$testable = LiVue::test(Counter::class);
// Get property value
$count = $testable->get('count');
// Get component instance
$component = $testable->instance();
// Get rendered HTML
$html = $testable->html();
// Get snapshot (state + memo)
$snapshot = $testable->snapshot();
// Get last response
$response = $testable->call('increment')->response();
How It Works
The testing system executes the full component lifecycle server-side, simulating what happens during real AJAX requests:
-
1.
Component is instantiated and
mount()is called - 2. Initial render produces HTML and snapshot
-
3.
Each
set()orcall()runs a fullprocessUpdate()cycle - 4. Assertions check the resulting state and HTML
This ensures tests exercise the exact same code path as production requests.