class ExampleTest extends TestCase
{
public function setUp()
{
parent::setUp();
$this->base_url = config('app.url');
$response = $this->post($this->base_url . '/auth/login', [
'username' => 'root',
'password' => '123',
]);
// how to get the login session cookie?
}
public function testStep1()
{
// how to set the login session to this POST request?
$response = $this->post($this->base_url . '/step1', [
'attr_1' => 'foo',
'attr_2' => 'bar',
]);
...
}
public function testStep2()
{
// how to set the login session to this POST request?
$response = $this->post($this->base_url . '/step2', [
'attr_1' => 'abc',
'attr_2' => 'xyz',
]);
...
}
}
从上面的示例代码中,我要实现的是testStep1
和testStep2
必须按(创建对象的向导)的顺序进行。因此,我必须保持相同的会话。
有可能实现吗?
我在调用/auth/login
之后尝试了输出,$response->headers->getCookies()
的值是
array:1 [
0 => Symfony\Component\HttpFoundation\Cookie {#940
#name: "XSRF-TOKEN"
#value: "eyJpdiI6IjQwUKxYnZlQ0J3N1B0Vkp4VjBEWVE9PSIsInZhbHVlIj782RKOUh2UFhONFwvaVRPUm56YkJ1ekxxSXlCTmtYSFNyRUF3NTdCTWhBMHhEQis1VVU0OUFcL3pKQUcybTFwQjdad1I1em02V1d4bVhDZWR2NFluUTlxdz09IiwibWFjIjoiZWRjYjk2NWI1MTU3YmJlMGEwMDdiNjNkYmVkMjBjMWU3NTRmZjE5NmMyM2EwOTZlNWJmZmYwMmRmYmExMWE1MSJ9"
#domain: null
#expire: 1531218886
#path: "/"
#secure: false
#httpOnly: false
-raw: false
-sameSite: null
}
]
并且$response
的值是
Illuminate\Foundation\Testing\TestResponse {#843
+baseResponse: Illuminate\Http\RedirectResponse {#1040
#request: Illuminate\Http\Request {#856
#json: null
#convertedFiles: null
#userResolver: Closure {#916
class: "Illuminate\Auth\AuthServiceProvider"
this: Illuminate\Auth\AuthServiceProvider {#52 …}
parameters: {
$guard: {
default: null
}
}
use: {
$app: Illuminate\Foundation\Application {#19 …}
}
file: "./vendor/laravel/framework/src/Illuminate/Auth/AuthServiceProvider.php"
line: "85 to 87"
}
#routeResolver: Closure {#860
class: "Illuminate\Routing\Router"
this: Illuminate\Routing\Router {#167 …}
use: {
$route: Illuminate\Routing\Route {#204 …}
}
file: "./vendor/laravel/framework/src/Illuminate/Routing/Router.php"
line: "527 to 529"
}
+attributes: Symfony\Component\HttpFoundation\ParameterBag {#870
#parameters: []
}
+request: Symfony\Component\HttpFoundation\ParameterBag {#867
#parameters: array:2 [
"username" => "root"
"password" => "123"
]
}
+query: Symfony\Component\HttpFoundation\ParameterBag {#911
#parameters: []
}
+server: Symfony\Component\HttpFoundation\ServerBag {#871
#parameters: array:17 [
"SERVER_NAME" => "localhost.com"
"SERVER_PORT" => 80
"HTTP_HOST" => "localhost.com"
"HTTP_USER_AGENT" => "Symfony/3.X"
"HTTP_ACCEPT" => "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
"HTTP_ACCEPT_LANGUAGE" => "en-us,en;q=0.5"
"HTTP_ACCEPT_CHARSET" => "ISO-8859-1,utf-8;q=0.7,*;q=0.7"
"REMOTE_ADDR" => "127.0.0.1"
"SCRIPT_NAME" => ""
"SCRIPT_FILENAME" => ""
"SERVER_PROTOCOL" => "HTTP/1.1"
"REQUEST_TIME" => 1531204718
"PATH_INFO" => ""
"REQUEST_METHOD" => "POST"
"CONTENT_TYPE" => "application/x-www-form-urlencoded"
"REQUEST_URI" => "/auth/login"
"QUERY_STRING" => ""
]
}
+files: Symfony\Component\HttpFoundation\FileBag {#878
#parameters: []
}
+cookies: Symfony\Component\HttpFoundation\ParameterBag {#869
#parameters: []
}
+headers: Symfony\Component\HttpFoundation\HeaderBag {#913
#headers: array:6 [
"host" => array:1 [
0 => "localhost.com"
]
"user-agent" => array:1 [
0 => "Symfony/3.X"
]
"accept" => array:1 [
0 => "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
]
"accept-language" => array:1 [
0 => "en-us,en;q=0.5"
]
"accept-charset" => array:1 [
0 => "ISO-8859-1,utf-8;q=0.7,*;q=0.7"
]
"content-type" => array:1 [
0 => "application/x-www-form-urlencoded"
]
]
#cacheControl: []
}
#content: null
#languages: null
#charsets: null
#encodings: null
#acceptableContentTypes: null
#pathInfo: "/auth/login"
#requestUri: "/auth/login"
#baseUrl: ""
#basePath: null
#method: "POST"
#format: null
#session: Illuminate\Session\EncryptedStore {#924
#encrypter: Illuminate\Encryption\Encrypter {#919
#key: b"A╦k>ú8f\x10─ÌÜ8ØýxK\x01²┬Íî·»├\x1A³0▒S┘Ì"
#cipher: "AES-256-CBC"
}
#id: "XPMgecNkwFHbZbujhiuEaBqgMqFTLIqsuIzyvXv"
#name: "laravel_cookie"
#attributes: array:11 [
"_token" => "5lcOcLk9AqvSlWyLdHMKba1lJQ1UqD2rBBVCSav"
"locale" => "en"
"_previous" => array:1 [
"url" => "http://localhost.com/auth/login"
]
"_flash" => array:2 [
"old" => []
"new" => []
]
"sess_user_id" => 123
"sess_user_firstname" => "Foo"
"sess_user_lastname" => "Bar"
"sess_role" => "admin"
"login_web_59ba36add234f940abcf014c987ea4e30989d" => 123
]
#handler: Symfony\Component\HttpFoundation\Session\Storage\Handler\NullSessionHandler {#925
-sessionName: null
-prefetchId: null
-prefetchData: null
-newSessionId: null
-igbinaryEmptyData: "\x00\x00\x00\x02\x14\x00"
}
#started: false
}
#locale: null
#defaultLocale: "en"
-isHostValid: true
-isForwardedValid: true
basePath: ""
format: "html"
}
#session: Illuminate\Session\EncryptedStore {#924}
#targetUrl: "http://localhost.com/dashboard"
+headers: Symfony\Component\HttpFoundation\ResponseHeaderBag {#1039
#computedCacheControl: array:2 [
"no-cache" => true
"private" => true
]
#cookies: array:1 [
"" => array:1 [
"/" => array:1 [
"XSRF-TOKEN" => Symfony\Component\HttpFoundation\Cookie {#940
#name: "XSRF-TOKEN"
#value: "eyJpdiI6IjVyVmRNSmlcL1dYK0VOdiwj8RxamZBPT0iLCJ2YWx1ZSI6IjNSQWFzcVllSEIrSYwZnNNbk1vZ1NERVc2UVdJeGs91D6UG5hNGlHUmRnendJOUVtUnA3Rnk0TnVLYmI5UnJXSTlZR3dxS0wxMElmOFlaWDMzdG9RPT0iLCJtYWMiOiI0ZTZlNTAwNjFkZWFkOTEwN2M1Y2EzMGRjOWMzMmU4NzEzNmM5NWU2MzhhODFjOGJkYTU0YmZlMTM3M2ExNmE3In0="
#domain: null
#expire: 1531219118
#path: "/"
#secure: false
#httpOnly: false
-raw: false
-sameSite: null
}
]
]
]
#headerNames: array:5 [
"cache-control" => "Cache-Control"
"date" => "Date"
"location" => "Location"
"content-type" => "Content-Type"
"set-cookie" => "Set-Cookie"
]
#headers: array:4 [
"cache-control" => array:1 [
0 => "no-cache, private"
]
"date" => array:1 [
0 => "Tue, 10 Jul 2018 06:38:38 GMT"
]
"location" => array:1 [
0 => "http://localhost.com/dashboard"
]
"content-type" => array:1 [
0 => "text/html; charset=UTF-8"
]
]
#cacheControl: []
}
#content: """
<!DOCTYPE html>\n
<html>\n
<head>\n
<meta charset="UTF-8" />\n
<meta http-equiv="refresh" content="0;url=http://localhost.com/dashboard" />\n
\n
<title>Redirecting to http://localhost.com/dashboard</title>\n
</head>\n
<body>\n
Redirecting to <a href="http://localhost.com/dashboard">http://localhost.com/dashboard</a>.\n
</body>\n
</html>
"""
#version: "1.1"
#statusCode: 302
#statusText: "Found"
#charset: null
+original: null
+exception: null
}
}
很明显,会话cookie不在$response->headers->getCookies()
中,我不使用actingAs()
是因为用户成功登录后,将设置一些会话值,即sess_user_id
, sess_user_firstname
,sess_user_lastname
,sess_role
...
答案 0 :(得分:2)
在第一种情况下,我只会发出发布请求并检查cookie是否存在。
$response = $this->post($this->base_url . '/auth/login', [
'username' => 'root',
'password' => '123',
]);
$response->assertCookieNotExpired($cookieName);
注意:您可以使用标头获取cookie。 $response->headers->getCookies();
,但我认为我们不需要他们。
现在我们知道身份验证的工作原理,我们可以使用Laravel actingAs 帮助方法进行身份验证,然后按以下方式进行请求。
$user = // get your user.
$response = $this->actingAs($user)->post($this->base_url . '/step1', [
'attr_1' => 'foo',
'attr_2' => 'bar',
]);
做出各种喜欢的断言(检查cookie,根据需要进行会话)
$response->assertSessionHas($key, $value);
在转到第三种情况之前,您应该知道最好分别测试每个部分。简而言之,您的测试不应该相互依赖,那么对于第三种情况我们可以做什么?我们知道我们的第三种情况取决于第二种情况,并且我们已经测试了先前的过程。现在我们只想测试我们的第三种情况是否有效。因此,为什么不使用Laravel帮助器 withSession 自己添加此请求所需的会话值。
$response = $this->actingAs($user)
->withSession(['foo' => 'bar'])
->post($this->base_url . '/step2', [
'attr_1' => 'abc',
'attr_2' => 'xyz',
]);
现在您可以再次声明。检查所有可用的assertions的列表。
答案 1 :(得分:0)
安装Mockery Mockery是一个简单而灵活的PHP模拟对象框架,可用于与PHPUnit进行单元测试
composer require mockery/mockery --dev
LoginController
public function authenticate(Request $request)
{
$credentials = $request->only('email', 'password');
if (Auth::attempt($credentials)) {
// Authentication passed...
// Get the currently authenticated user...
$user = Auth::user();
return redirect()->route('profile');
}else{
return redirect()->intended('loginform');
}
}
示例测试
public function testLoginSuccess()
{
$credential = [
'email' => 'xxx',
'password' => 'yyy'
];
Auth::shouldReceive('attempt')->once()->withAnyArgs()->andReturn(true);
Auth::shouldReceive('user')->once()->withAnyArgs()->andReturn(true);
$response = $this->post('/login',$credential);
$response->assertRedirect('/profile');
}
此示例向您展示了如何在单元测试中模拟Auth Facades。
Auth :: attempt返回true
Auth ::用户返回true
您可以根据需要使用Mockery模拟对象。
答案 2 :(得分:0)
检查phpunit.xml,默认情况下SESSION_DRIVER的值设置为'array',将其更改为'file'