【问题标题】:TDD: Cant Test One Method's behaviour until another (public) method is implemented, and vice versaTDD:在实现另一种(公共)方法之前无法测试一种方法的行为,反之亦然
【发布时间】:2021-01-28 01:29:22
【问题描述】:

我同意在测试时我们应该使用公共 API 来确保我们的测试不会脆弱的观点。 IE。不要测试实现,测试行为。

想象一下我的公共 API 将具有两种方法或功能的情况。一种是更新内部私有状态的命令方法。另一种是查询方法,它从这个私有状态中检索信息。我不想仅仅为了测试而公开私有字段。

挑战在于我如何在确认一个需要另一个的行为时开始编写我的测试,同时遵循 TDD 方法。

让我们想象一个这样的场景:

class Manager:

    def Manager():
        _reserved_resources = []

    def reserve_resource(id):
    # Creates a new resource and reserves if none exist in the pool, or reserves an existing one. Does not return anything.

    def retrieve_reserved_resource(id):
    # Returns a reserved resource, or returns None if not previously reserved.

如果我使用公共 API,则在实现 retrieve_reserved_resource 之前,我无法测试 reserve_resource 的行为。在 reserve_resource 实施之前,我无法测试 retrieve_reserved_resource 是否具有正确的行为。

如果我的第一个测试是:

def test_reserve_resource_when_no_resources_exists_creates_a_new_resource()

retrieve_reserved_resource 尚未实现时,我如何确认此行为。

我是否只是像实现 retrieve_reserved_resource 一样编写测试,这样,当测试变为绿色时,我将拥有两种方法的基本实现?

这是非常特定于 TDD 的。也明白这是一个人为的例子,但希望它能澄清问题。基本上这是一个先有鸡还是先有蛋的场景,其中命令方法和查询方法都需要彼此确认它们的行为。那么从哪里开始呢?

【问题讨论】:

    标签: unit-testing tdd public


    【解决方案1】:

    我的启发是“先读后写”——如果你不能测量被测代码的行为,你就不能“驱动”任何设计,或者任何实现。

    所以第一个测试都是“在最简单的情况下我应该测量什么”的变体?

    m = Manager()
    assert m.retrieve_reserved_resource(12345) is None
    

    然后,当我们对这些测试感到满意时,我们会继续测量在稍微复杂一点的情况下会发生什么。

    m = Manager()
    m.reserve_resource(12345)
    assert m.retrieve_reserved_resource(12345) is not None
    

    【讨论】:

    • 谢谢。这有助于加强我想采取的方向,在“写入/命令”方面之前关注“读取/查询”方面的附加细节。这是非常有意义的,并且是一个很好的小指南。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-25
    • 2020-08-02
    • 1970-01-01
    • 2021-06-05
    • 1970-01-01
    相关资源
    最近更新 更多