我想测试不同的客户从网上商店购买.客户来自不同的国家和不同的增值税适用于他们.通常da是来自数据库.现在我想模拟它.我已经做了它与产品在一个购物车.我已经这样做了:
protected function setUp(): void {
$this->stub = $this->createMock(Cart::class);
$product = (object) [
'did' => '212814',
'amount' => 1,
'id' => '1664442400',
'price' => '49.22',
'name' => 'Table 150 cm',
];
$this->stub->method('getCartProducts')->willReturn([$product]);
我不知道这样做是否正确。
对于购物车来说,只有一个产品并在不同的测试中使用它是可以的。但是我有不同的客户,他们有不同的价值观。我应该如何创建他们?我应该这样做吗:
$this->stubCustomer1 = $this->createMock(Customer::class);
$customer1 = (object) ['name' => 'Paul', 'country' => 'UK']
和
$this->stubCustomer2 = $this->createMock(Customer::class);
$customer2 = (object) ['name' => 'Paulo', 'country' => 'Italy']
等等。就像这样,每次执行设置时都会创建所有这些。但并不是所有都需要。在每个测试方法中创建客户会更好吗?或者还有其他方法?
1条答案
按热度按时间pgky5nke1#
单元测试的常见模式是Arrange-Act-Assert(AAA)。这意味着每个测试(即测试类中的每个方法)都应该为其本身准备所有需要的状态。这使得测试彼此更加隔离,并且更容易推理。
我建议遵循这种模式。这意味着您直接在测试方法中进行所有特定于用例的准备,而不是在
setUp()
方法中。setUp()
只能用于一些通用的准备,大多数是技术性的,而不是域感知的,例如重置一些依赖项,清除存储等。为了简化测试的
Arrange
步骤,您可以为不同类型的客户创建工厂方法。并且没有必要像$this->stubCustomer2
那样将每个存根保存在class属性中,只需创建它们并在case中使用,然后在new case中创建new。所以,你的测试可能看起来像这样:
另外,考虑尽可能地避免测试替身,以支持真实的的实现。也就是说,创建真正的客户,产品和购物车,而不是存根可能会更好。这将使未来的支持测试更容易。在单元测试中,真正需要替身的只有依赖于进程外的东西的类,如DB,网络或文件系统。