0

I'm trying to run a single test where multiple users are performing actions. There is either a bug in the actingAs() function, or I am completely missing something trivial. So here's the scenario. I have a social media site. I want to login as one user, perform an action (follow another user), then login as the other user and submit a post. The first user passed into the actingAs function persists throughout all subsequent actions, even when I explicitly call actingAs for the 2nd user, or even use my logout route to try and logout the first user. Here is the code:

//Create the user that will make the post
$user = User::factory()->subscriber()->active()->create();

//Create the user that will follow the first user
$follower = User::factory()->subscriber()->active()->create();

//Login as the 'follower' and perform the action to follow the first user
$this->actingAs($follower)->post('/ajax/follow/User/'.$user->id);

//Now, try to login as the first user and make the post
$request = ['id' => 1,'body' => 'I have a body'];
$response = $this->actingAs($user)->post('/posts/add',$request);

The above fails because, even though I call actingAs($user) on the last line, when I data dump the authorized user, I find that I am still logged in as $follower, even though I've specifically tried to make the post as $user. I've tried putting manual Auth::logout() functions inline, I've tried hitting the logout route while acting as $follower, and a few other things. No matter what, it seems that the first user that you actAs becomes the only user that you can act as during a single test.

Does anybody have any experience with this and how to solve the issue? Thanks in advance.

eResourcesInc
  • 948
  • 1
  • 9
  • 17
  • Your issue is that you do not test like this, those are 2 different/separate feature tests. On one test you must have all data set (what it means for a follower to follow you) and test whatever you need (post), and for the other, you have no follower and someone follows you (or you follow someone). Check [an answer I had in one post about testing](https://stackoverflow.com/questions/69150653/how-to-feature-test-more-complicated-cases-on-laravel-using-phpunit/69155061#69155061), maybe it will help you understand more. – matiaslauriti Mar 30 '22 at 16:27
  • This is not helpful. There is no 'correct' way to test. My question is very specific, and I reject the idea that there is no scenario in which you may want to run a single test with two separate user actions. I am not testing whether the actions work, I'm testing whether the chain of actions leads to an expected result. – eResourcesInc Mar 30 '22 at 16:49
  • You can and should "simulate" what the previous action meant, that is the way of testing this. A test should ONLY test 1 action, period, that is not debatable, it is common practice. If you don't like that, then it is how you think you should test and I am not against it. I recommend you to look more into `feature testing` Laravel code, look for blogs and tutorials and you will see (if the video is good...) that everyone recommends to test one action. Can you explain what is the full chain? Like what is each part going to "trigger"? – matiaslauriti Mar 30 '22 at 20:43

1 Answers1

2

I came across the same problem and I did this:

$this->app->get('auth')->forgetGuards();

between my requests

So your code should look like this:

//Create the user that will make the post
$user = User::factory()->subscriber()->active()->create();

//Create the user that will follow the first user
$follower = User::factory()->subscriber()->active()->create();

//Login as the 'follower' and perform the action to follow the first user
$this->actingAs($follower)->post('/ajax/follow/User/'.$user->id);

$this->app->get('auth')->forgetGuards();

//Now, try to login as the first user and make the post
$request = ['id' => 1,'body' => 'I have a body'];
$response = $this->actingAs($user)->post('/posts/add',$request);
William Martins
  • 357
  • 2
  • 14