我的專案使用Laravel,我是單元/功能測驗的新手,所以我想知道在撰寫測驗時,什么是最好的方法來處理更復雜的功能案例?
讓我們以這個測驗為例:
// tests/Feature/UserConnectionsTest.php
public function testSucceedIfConnectAuthorised()
{
$connection = factory(Connection::class)-> make([
'sender_id' => 1,
'receiver_id' => 2,
'accepted' => false,
'connection_id' => 5,
]);
$user = factory(User::class)-> make([
'id' => 1,
]);
$response = $this->actingAs($user)-> post(
'/app/connection-request/accept'。
[
'accept' => true,
'request_id' => $connection-> id,
);
$response->assertLocation('/')->assertStatus(200) 。
}
所以我們有這樣的情況,我們在兩個用戶之間有一些連接系統。在DB中存在一個由其中一個用戶創建的Connection條目。現在為了使它成為一個成功的連接,第二個用戶必須批準它。問題出在UserController中,它通過connectionRequest接受這個連接:
//app/Http/Controllers/Frontend/UserController.php
public function connectionRequest(Request $request)
{
//我們檢查用戶是否沒有試圖接受連接。
//他自己發起的連接。
$connection = $this->repository-> GetConnectionById($request->get('request_id')) 。
$receiver_id = $connection-> receiver_id。
$current_user_id = auth()-> user()->id。
if ($receiver_id !==$current_user_id) {
abort(403)。
}
[...]
}
//app/Http/Repositories/Frontend/UserRepository.php
public function GetConnectionById($id)
{
return Connection::where('id', $id)->first()。
}
所以我們在測驗函式中得到了這個假的(工廠創建的)連接,然后我們不幸地使用它的假id在真實的DB中運行檢查,這不是我們想要的:(
)在研究中,我發現了一個創建介面的想法,這樣我們就可以根據我們是否在測驗,提供不同的方法機構。就像這里的GetConnectionById(),這樣就可以很容易地為測驗案例偽造答案。這看起來不錯,但是:
uj5u.com熱心網友回復:
我將嘗試幫助你,當有人開始進行測驗時,這一點都不容易,特別是如果你沒有一個強大的框架(甚至根本沒有框架)。
所以,讓我試著幫助你:
- 因此,為了實作這一點,你必須在
- 另外,使用
RefreshDatabase特質。因此,每次你運行測驗時,它都會洗掉所有的東西,再次遷移你的表并運行測驗。
phpunit.xml中定義正確的環境變數,所以當你只運行測驗時,你不需要做魔法就可以作業。
product,一個user和一個invoice與product和user有關。您不需要創建notifications或任何與此無關的東西。你必須擁有你期望在真實情況下擁有的東西,但沒有任何額外的東西,所以你可以真正地測驗它在最小的東西下完全作業。
request或controllers或任何類似的代碼。如果你正在模擬這些代碼,你就做錯了事。(一旦你真正了解了如何測驗,你就會隨著經驗了解到這一點)if和must以及類似的措辭,而是使用when和should。例如,你的測驗testSucceedIfConnectAuthorised應該被命名為testShouldSucceedWhenConnectAuthorised。
RepositoryPattern,它是一個反模式。它并不是最糟糕的東西, 但我建議有一個Service類(不要與Service Provider混淆, 我指的類是一個普通的類, 它仍然被稱為Service)來實作你的愿望. 但是, 你仍然可以通過谷歌來了解這個問題和Laravel, 你會看到每個人都不鼓勵在Laravel中使用這種模式. Connection::where('id', $id)->first()與Connection::find($id)完全相同。
URLs(就像你在你的測驗中做的那樣),因為如果你依靠route('url.name')并且名稱匹配,但真正的URL是/api/asdasd,你將永遠無法測驗出這個URL是你想要的那個。所以,恭喜你了 ! 很多人都沒有這樣做,這是不對的。
因此,為了幫助你的案例,我將假設你有一個清晰的資料庫(沒有表的資料庫,RefreshDatabase特性將為你處理這個問題)。
我將會把你的第一個測驗寫成這樣:
public 功能 testShouldSucceedWhenConnectAuthorised()
{
/**。
* 我不知道你的關系如何,但我希望
* 你能通過這個得到主要的想法。只要創建
* 當你有了這個時,你應該期望有什么
*測驗案例
*/
$connection = factory(Connection::class)-> create([
'sender_id' => factory(Sender::class)-> create()->id,
'receiver_id' => factory(Reciever::class)-> create()->id。
'accepted' => false。
'connection_id' => factory(Connection::class)-> create()->id,
]);
$response = $this->actingAs(factory(User::class)-> create()
->post()
'/app/connection-request/accept'。
[
'accept' => true,
'request_id' => $connection-> id
]
);
$response->assertLocation('/')
->assertOk()。
}
那么,除了指向你的測驗資料庫(本地)的phpunit.xml環境變數外,你不應該改變任何東西,它應該在你的代碼中不改變任何東西的情況下作業。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/318660.html
標籤:
