I don't think I have tried this as I'd usually populate something in the factory immediately. However, t it might simply be that you are asserting that null (the message title) is the same as an empty string (the document).
assertSee on a non existing property returns green
Hello everyone,
I have a couple of years of experience with Laravel but I am completely new to TDD world. Just learning and Laracasts has been a great resource, as always.
I found one strange behavior with assertSee method when following the step-by-step TDD approach so I was wondering if this was normal.
I have a simple test for viewing a listing of messages:
/** @test */
public function viewing_all_messages()
{
$message = factory('App\Message')->create();
$this->get('/messages')
->assertSee($message->title);
}
A brand new factory is in place, no fields defined. Model is also generated, fresh. Migration is there, no fields added (id, created_at and updated_at is all there is), I have the route defined to point to MessagesController@index. In controller I have just a simple few lines:
public function index()
{
$messages = Message::all();
return view('messages.index', compact('messages'));
}
Nothing fancy there.
I have the view created but nothing inside. Blank file completely.
Until this point I followed the TDD approach by solving one error at a time and running the test after each solved to get to the next one. But here when I created the view before writing anything inside the file, to my surprise, the test passed. I expected to see something like: title property does not exist on the message object or so. After some debugging and running through the code I understood that non existing property that was put there as part of programming by wishful thinking (which is the message title since it is not defined in migration nor the factory) is actually null. And since the assertSee method behind the scenes converts the passed value to string before comparing it to the view contents (converting null to string in PHP returns an empty string "") it makes the test pass because the contents of my view is also an empty string. But, at least to me, this looks like the test is wrongly passing.
I have seen @JeffreyWay using this approach before in his tests (Let's Build a Forum with Laravel and TDD series for example), so I was wondering if it is legitimate to have it passing at this point.
What do you think?
You can call any property on an Eloquent model and will get null unless it has an accessor (virtual/computed), a property on the Model instance, a column on the table or a relation result.
If you source-dive the Model class (and its HasAttributes trait), you will see there is a magic __get method which accepts the property name you are trying to get and attempts to get a value for that property from the model in the order described above. If none is found, null is returned as the result for that property.
Please or to participate in this conversation.