单元测试是否意味着测试必须被模拟?

单元测试是否意味着测试必须被模拟?

问题描述:

不单元测试意味着测试必须嘲笑或单元测试的定义可以是不嘲笑?单元测试是否意味着测试必须被模拟?

例如下面,此试验是嘲笑,所以它是单元测试:下面

/** 
* @test 
*/ 
public function it_should_return_true_if_ssh_client_is_connected() 
{ 
    $this->phpSecLibShh->shouldReceive('isConnected')->andReturn(true)->once(); 

    $this->assertTrue($this->shell->connected($this->phpSecLibShh)); 
} 

实施例,是这样的单元测试或集成测试?我不清楚这个:

/** 
* @test 
*/ 
public function it_should_get_half_price_discount() 
{ 
    $cost = 50; 

    $order = new Order(); 

    // It does not connect to database or any other service 
    $discounted = $order->discount(Order::DISCOUNT_HALF_PRICE, $cost); 

    $this->assertEquals(25, $discounted); 
} 

嘲笑的主要思想是解耦依赖。单元测试不应该有任何的依赖。说你的业务逻辑连接到数据库层,然后连接到数据库。现在你正在编写一个单元测试来测试你的业务逻辑。如果您不是将数据库基础层与业务逻辑分离开来,那么您的单元测试将会发挥作用,并且不会发生这种情况。所以你应该做的是将数据库依赖注入到业务逻辑层,并在编写单元测试模拟该依赖时。

长话短说,你不必总是模拟单元测试,但如果任何依赖性那么就应该被嘲笑。如果您的测试有任何依赖性(比如数据库的依赖,文件相关性等),则无法进行测试单元测试,但集成测试

+0

不按照Martin Fowler的(https://martinfowler.com/bliki/UnitTest.html)... [单元测试的定义,对于他(和Kent Beck,JUnit和TDD的创造者),在单元测试被测试的单元不一定必须与其依赖关系隔离。就个人而言,我认为孤立的单元测试通常是一个坏主意,应该避免。 –

+0

@Rogério我很欣赏你的评论。单元测试是我们运行了很多次的东西。如果我们更改事件一行代码,我们可以运行单元测试,以确保更改不会影响到目前为止编写的任何功能逻辑。现在认为,在您的业务逻辑中,您正在调用外部付费Web服务的业务逻辑。如果你不嘲笑那项服务,那么你每次运行单元测试都会付钱。我同意测试应该被隔离,但它也应该与依赖隔离。隔离意味着一个代码单元。 –

+0

当然,如Fowler的文章中提到的那样,当调用“笨拙的合作者(如远程信用卡验证系统)”时,确实有意义进行模拟。但是,这种情况应该是例外而不是常态,而且在大多数现实世界的代码库中都非常罕见。嘲笑图书馆的问题是没有经验的开发人员往往会滥用它们(以及滥用它们,因为它们固有的复杂性)。我从开发一个嘲笑图书馆12年的经验中了解到这一点,同时支持用户,并看到他们经常犯的错误。 –

维杰,从我的经验,球队将是最好的法官来决定他们是否需要一个孤独的/社交/自适应单元测试策略,因为没有“一刀切”的解决方案。

话虽如此,我相信是适应性可能更实用。几乎所有的中大型单片应用程序都将具有至少一种外部依赖性,这在开发/测试环境中可能不可用(例如:支付网关/决策引擎)。模拟数据将是我们唯一的选择。然而,在相同的单元测试案例中,我们也可以组织另一个社交场景(通过在同一个类/名称空间中调用另一个函数)。第二个函数甚至有可能在单独的模拟测试用例上有它。因此,它可以成为一种适应性的单元测试策略,其中团队根据他们所称的单元采取集体立场,并根据情景基础在场景中使用何种策略。 我们也应该记住,当我们开始构建部署管道时,我们的单元测试用例可以作为自动化过程的一部分执行,而自动化过程本身就是供应环境的一部分。因此,将我们的单元测试用例与任何数据库/文件依赖关系隔离起来可能是有益的。

在未来,当越来越多的应用到移动微服务架构和集装箱化运输,我们将有各地的单元测试策略更加清晰使用。开发/部署将在无状态和可独立部署/管理的块中完成。像Docker Daemon API这样的工具可以用来启动一个托管特定相关/依赖服务/功能的容器,并将其作为我们测试用例执行的一部分运行,这样可以防止我们嘲笑其他服务,因为我们可以轻松激活具有相关服务的轻量级容器并对其进行测试。