Just to add to this: Using the DatabaseMigrations trait instead solved the issue, however I'm still curious as to why I was having issues with my Note::search method when using the RefreshDatabase trait
No matches from fulltext search index query within laravel test suite
So I have a very simple search method on a "Note" model that looks like this:
public static function search($query)
{
$results = self::whereRaw("Match(name,body) AGAINST('$query')")
->get();
return self::processSearchResults($results, $query);
}
The processSearchResults() just attaches some extra fields onto the results - nothing to worry about.
I'm trying to create a simple unit test which creates 2 notes, and then does a search which should return one of the notes. I've hit a hurdle where my search method is returning an empty collection which only occurs when I use the RefreshDatabase trait (to clear out test data).
My first thoughts was that the data wasn't being persisted to the database but a simple Note::all() call proved that the 2 records were present. My unfinished test looks like this:
public function test_searching_notes_returns_results_with_matches_in_title()
{
// GIVEN 2 note records, one containing the word "PHP" in the title and one doesn't
factory(Note::class, 1)->create([
'name' => "Something PHP Something"
]);
factory(Note::class, 1)->create([
'name' => "Something C# Something"
]);
// WHEN we search for the word PHP
$results = Note::search("PHP");
// THEN it should return the correct note
// This works when I don't use the RefreshDatabase trait, otherwise it's empty
print_r($results->toArray());
}
Any ideas what might be wrong here
FULLTEXT indexes don't work in transactions: https://dev.mysql.com/doc/refman/en/innodb-fulltext-index.html#innodb-fulltext-index-transaction
If you want to use RefreshDatabase, you have to commit the transaction and then clean up the database yourself:
public function testMatchAgainstViaHttp()
{
factory(Post::class, 50)->create([
'title' => 'Mauris accumsan eros quis efficitur'
]);
factory(Post::class, 7)->create([
'title' => 'Lorem ipsum dolor sit amet'
]);
\DB::commit();
$this->assertCount(57, Post::all());
$response = $this->withHeaders(['Accept' => 'application/json'])
->get('/matchagainst');
$response->assertJsonCount(7);
Post::truncate();
}
Please or to participate in this conversation.