Skip to content

Conversation

@sangct-1630
Copy link

Purpose/Notes

Write UnitTest Module 3->7

Screenshot

  1. Module 03
    Screenshot from 2021-05-20 02-10-53
  2. Module 04
    Screenshot from 2021-05-20 02-11-00
  3. Module 05
    Screenshot from 2021-05-20 02-11-06
  4. Module 06
    Screenshot from 2021-05-20 02-11-25
  5. Module 07
    Screenshot from 2021-05-20 02-11-32

Checklist (*)

  • Pull request has been self-reviewed
  • Pull request has a meaningful description of its purpose
  • All commits are accompanied by meaningful commit messages
  • All CI builds passed successfully (all builds are green)

@sangct-1630 sangct-1630 changed the title Do homework [SangCT] Do homework May 20, 2021
Comment on lines +26 to +37
/**
* A basic unit test example.
*
* @return void
*/
public function test__contruct()
{
$controller = new ProductController($this->productServiceMock);

$this->assertInstanceOf(ProductController::class, $controller);

}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test constructor có ý nghĩa gì không em?


}

public function test_index()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test index là test cái gì, tên test case nên thể hiện được mục đích của test case

Mục 1 trong checklist:

Comment on lines +60 to +73
$request = $this->mock(CheckoutRequest::class);
$request->shouldReceive('input')
->once()
->with('total_products')
->andReturn($input);

$this->productServiceMock->shouldReceive('calculateDiscount')
->with($input)
->once()
->andReturn(7);

$controller = new ProductController($this->productServiceMock);

$this->assertInstanceOf(JsonResponse::class, $controller->checkout($request));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cái này viết theo cách dùng HTTP tests như ở test_index được không? Sao case này lại viết cách khác nhỉ?

Comment on lines +12 to +20
public function test_rules()
{
$request = new CheckoutRequest();

$this->assertSame([
'total_products' => 'required|array',
'total_products.*' => 'nullable|integer|min:0',
], $request->rules());
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines +40 to +76
/**
* @param $totalProducts
* @param $expectedValue
* @dataProvider provideValidTotalProductsData
* */
public function test_calculate_discount_with_valid_data($totalProducts, $expectedValue)
{
$discount = $this->productService->calculateDiscount($totalProducts);
$this->assertEquals($expectedValue, $discount);
}

public function provideValidTotalProductsData()
{
return [
[
[
1 => 2,
2 => 2,
3 => 2,
], 5
],
[
[
1 => 0,
2 => 4,
3 => 4,
], 7
],
[
[
1 => 2,
2 => 3,
3 => 3,
], 12
],
];
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Viết như này đọc khá khó hiểu, ít nhất nên đặt tên cho từng dataset hoặc là tách ra các case riêng biệt

  • Input chỉ bao gồm các số, nhìn như các số ngẫu nhiên, không thể hiện được điều kiện input đầu vào là gì => Các key input nó đã được đặt tên bằng const trong class Product thì nên sử dụng ở đây

Với cả thiếu case nhé?

Anh thấy bài này có thể chia case theo kết quả mong muốn thì sẽ rất dễ sinh input, có 4 kết quả mong muốn:

  • Exception => invalid data
  • Discount = 5 => only cravat white discount
  • Discount = 7 => only total quantity discout
  • Discount = 12 => both discounts

Hoặc có thể bám theo lý thuyết C1

        if ($cravat < 0 || $whiteShirt < 0 || $others < 0) {
            // (1)
            throw new InvalidArgumentException();
        } // else (2)

        if ($cravat > 0 && $whiteShirt > 0) {
            // (3)
            $discount = self::CRAVAT_WHITE_SHIRT_DISCOUNT;
        } // else (4)

        if (($cravat + $whiteShirt + $others) >= self::TOTAL_PRODUCT_TO_DISCOUNT) {
            // (5)
            $discount += self::QUANTITY_DISCOUNT;
        } // else (6)
  • (1) => End
  • (2) (3) (5) => End
  • ...

Và nên thêm 1 case để test cận cho điều kiện >= 7, vì dấu >= và dấu > thường rất dễ nhầm

Copy link
Contributor

@tuanpt-0634 tuanpt-0634 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A đã comment gợi ý cho 1 vài bài, nên đọc lại guideline, checklist và refactor cả những phần khác

@tuanpt-0634 tuanpt-0634 mentioned this pull request May 25, 2021
4 tasks

$controller = new ProductController($this->productServiceMock);

$this->assertInstanceOf(JsonResponse::class, $controller->checkout($request));
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Đoạn này nên có thêm assert cho
->json(['discount' => $discount]);
Để xem xem là người dùng có truyền discount đúng cái trả về từ service không

$this->assertEquals($expectedValue, $discount);
}

public function provideValidTotalProductsData()
Copy link

@namttdh namttdh May 29, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ở đây thiếu miss mất 1 case.
Giả sử các trường hợp dưới đây không tồn tại thì ra sao?

$totalProducts[Product::CRAVAT_TYPE] 
$totalProducts[Product::OTHER_TYPE]
$totalProducts[Product::WHITE_SHIRT_TYPE]

Ngoài thì thì a cũng để ý các trương logic so sánh >= hiện tại anh chỉ đang test các trường hợp > nhưng đối với các trường hợp = thì đang không test


public function test_index()
{
$this->calendarServiceMock->shouldReceive('getDateClass')
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trong controller này có logic, nên phải làm sao test đưuọc cả logic đấy. Muốn test được logic đấy thì có 2 cách
1 là cái mock này không nên chỉ shouldReceiveandReturn luôn.
Mình nên làm để biết thêm là cái method getDateClass gọi bao nhiêu lần và những tham số truyền vào là gì
2 là
$response->assertViewHas('calendars'); thì mình phải assert xem cả cái data của nó nữa

* */
public function test_handle_discount($detailOrder, $expectedValue)
{
$resultOrder = $this->orderService->handleDiscount($detailOrder);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trong provider này nên thêm có 1 case nữa check độ chính xác tới 2 chữ số thập phân vì cái round nó có thêm tham số thứ 2 là 2

$infoBill['price'] = round(($detailOrder['price'] * 80) / 100, 2);

Cái này nice to have 😄

Ngoài ra nữa thì anh để ý các logic >= nhá

$this->assertEquals($expectedValue, $time);
}

public function provideData()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ở đây sẽ có 1 case, là giả sử không truyền vào has_watch thì kết quả sẽ ra sao.
Tất nhiên là không truyền vào has_watch thì default nó là false thì nó sẽ trùng 1 trong các số test của mình. Nhưng về cơ bản thì vẫn phải có case là không truyền vào cái gì cả

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants