@@ -1584,7 +1584,6 @@ final class InvalidTest extends TestCase
1584
1584
public function suspending_a_new_subscription_with_cannot_suspend_new_policy_is_not_possible(): void
1585
1585
{
1586
1586
// Here we need to create a new subscription, it is not possible to change $this->subscription to a new subscription
1587
- self::assertTrue(true);
1588
1587
}
1589
1588
}
1590
1589
```
@@ -1653,10 +1652,174 @@ final class ValidTest extends TestCase
1653
1652
1654
1653
### Exposing private state
1655
1654
1655
+ :x : Bad:
1656
+
1657
+ ``` php
1658
+ final class Customer
1659
+ {
1660
+ private CustomerType $type;
1661
+
1662
+ private DiscountCalculationPolicyInterface $discountCalculationPolicy;
1663
+
1664
+ public function __construct()
1665
+ {
1666
+ $this->type = CustomerType::NORMAL();
1667
+ $this->discountCalculationPolicy = new NormalDiscountPolicy();
1668
+ }
1669
+
1670
+ public function makeVip(): void
1671
+ {
1672
+ $this->type = CustomerType::VIP();
1673
+ $this->discountCalculationPolicy = new VipDiscountPolicy();
1674
+ }
1675
+
1676
+ public function getCustomerType(): CustomerType
1677
+ {
1678
+ return $this->type;
1679
+ }
1680
+
1681
+ public function getPercentageDiscount(): int
1682
+ {
1683
+ return $this->discountCalculationPolicy->getPercentageDiscount();
1684
+ }
1685
+ }
1686
+ ```
1687
+
1688
+ ``` php
1689
+ final class InvalidTest extends TestCase
1690
+ {
1691
+ public function testMakeVip(): void
1692
+ {
1693
+ $sut = new Customer();
1694
+ $sut->makeVip();
1695
+
1696
+ self::assertEquals(CustomerType::VIP(), $sut->getCustomerType());
1697
+ }
1698
+ }
1699
+ ```
1700
+
1701
+ :heavy_check_mark : Good:
1702
+
1703
+ ``` php
1704
+ final class Customer
1705
+ {
1706
+ private CustomerType $type;
1707
+
1708
+ private DiscountCalculationPolicyInterface $discountCalculationPolicy;
1709
+
1710
+ public function __construct()
1711
+ {
1712
+ $this->type = CustomerType::NORMAL();
1713
+ $this->discountCalculationPolicy = new NormalDiscountPolicy();
1714
+ }
1715
+
1716
+ public function makeVip(): void
1717
+ {
1718
+ $this->type = CustomerType::VIP();
1719
+ $this->discountCalculationPolicy = new VipDiscountPolicy();
1720
+ }
1721
+
1722
+ public function getPercentageDiscount(): int
1723
+ {
1724
+ return $this->discountCalculationPolicy->getPercentageDiscount();
1725
+ }
1726
+ }
1727
+ ```
1728
+
1729
+ ``` php
1730
+ final class ValidTest extends TestCase
1731
+ {
1732
+ /**
1733
+ * @test
1734
+ */
1735
+ public function a_vip_customer_has_a_25_percentage_discount(): void
1736
+ {
1737
+ $sut = new Customer();
1738
+ $sut->makeVip();
1739
+
1740
+ self::assertEquals(25, $sut->getPercentageDiscount());
1741
+ }
1742
+ }
1743
+ ```
1744
+
1656
1745
### Leaking domain details
1657
1746
1747
+ ``` php
1748
+ final class DiscountCalculator
1749
+ {
1750
+ public function calculate(int $isVipFromYears): int
1751
+ {
1752
+ Assert::greaterThanEq($isVipFromYears, 0);
1753
+ return min(($isVipFromYears * 10) + 3, 80);
1754
+ }
1755
+ }
1756
+ ```
1757
+
1758
+ :x : Bad:
1759
+
1760
+ ``` php
1761
+ final class InvalidTest extends TestCase
1762
+ {
1763
+ /**
1764
+ * @dataProvider discountDataProvider
1765
+ */
1766
+ public function testCalculate(int $vipDaysFrom, int $expected): void
1767
+ {
1768
+ $sut = new DiscountCalculator();
1769
+
1770
+ self::assertEquals($expected, $sut->calculate($vipDaysFrom));
1771
+ }
1772
+
1773
+ public function discountDataProvider(): array
1774
+ {
1775
+ return [
1776
+ [0, 0 * 10 + 3], //leaking domain details
1777
+ [1, 1 * 10 + 3],
1778
+ [5, 5 * 10 + 3],
1779
+ [8, 80]
1780
+ ];
1781
+ }
1782
+ }
1783
+ ```
1784
+
1785
+ :heavy_check_mark : Good:
1786
+
1787
+ ``` php
1788
+ final class ValidTest extends TestCase
1789
+ {
1790
+ /**
1791
+ * @dataProvider discountDataProvider
1792
+ */
1793
+ public function testCalculate(int $vipDaysFrom, int $expected): void
1794
+ {
1795
+ $sut = new DiscountCalculator();
1796
+
1797
+ self::assertEquals($expected, $sut->calculate($vipDaysFrom));
1798
+ }
1799
+
1800
+ public function discountDataProvider(): array
1801
+ {
1802
+ return [
1803
+ [0, 3],
1804
+ [1, 13],
1805
+ [5, 53],
1806
+ [8, 80]
1807
+ ];
1808
+ }
1809
+ }
1810
+ ```
1811
+
1658
1812
### Mocking concrete classes
1659
1813
1814
+ :x : Bad:
1815
+ :heavy_check_mark : Good:
1816
+
1660
1817
### Testing private methods
1661
1818
1662
- ### Time as a volatile dependency
1819
+ :x : Bad:
1820
+ :heavy_check_mark : Good:
1821
+
1822
+ ### Time as a volatile dependency
1823
+
1824
+ :x : Bad:
1825
+ :heavy_check_mark : Good:
0 commit comments