代码之家  ›  专栏  ›  技术社区  ›  anonymous

TDD:向测试状态添加方法

  •  0
  • anonymous  · 技术社区  · 15 年前

    所以,我开始为一个简单的程序(旁边的玩具游戏)写一些逻辑。您有一个特定的Ship(称为设置),它是Ship+模块。从一个基于船的空设置开始,然后向该设置添加模块。船上还有一组模块位置编号。

    var setup = new Setup(ship); // ship is a stub (IShip) defined someplace else
    var module = new Mock<IModule>().Object;
    setup.AddModule(module, 1); // 1 = which position
    

    这就是我测试方法中的代码。我现在需要在这段代码上声明。嗯,我需要一个getter方法,对吗?

    Assert.AreEqual(module, setup.GetModule(1));
    

    这听起来可能很愚蠢,我什么也不担心,但出于某些愚蠢的原因,我担心添加一个方法来断言测试通过了。

    这很好吗?事实上,这是TDD推出的设计过程的一部分吗?例如我 知道 我需要一个addmodule方法,因为我想测试它,这需要一个getmodule方法来测试,这只是我通过TDD设计的一个演进。

    或者这种味道是因为我甚至不知道在我的代码中是否真的需要getmodule,并且它只在测试中使用?

    例如,添加模块将最终影响设置的不同状态(装甲、盾牌、火力等)。问题是这些都会很复杂,我想从一个简单的测试开始。但最后,这些是我关心的公共属性——设置是由它的状态定义的,而不是由模块列表定义的。

    3 回复  |  直到 15 年前
        1
  •  2
  •   bryanbcook    15 年前

    有趣的问题。我很高兴听到你先写测试。

    如果您让设计通过测试实现,那么您更可能只构建您需要的部分。但这是最好的设计吗?也许不是,但不要让这让你泄气——你的添加方法是有效的!

    现在判断以后是否需要getmodule方法还为时过早。现在,构建您需要的功能,然后变为绿色,然后慢慢地重构它(再次从红色变为绿色),以获得您想要的设计。

        2
  •  1
  •   Yishai    15 年前

    改进设计的一部分是从一个简单的方法这样的小步骤开始,然后在足够的支持下成长为复杂的统计(最终放弃这个方法并更改测试)。在进行TDD时,不要期望编写的第一个测试针对的是理想的接口。随着设计的发展,会有一些乱七八糟的东西掉下来。

    也就是说,如果您没有看到该方法的公共目的,那么尝试尽可能地限制它对测试代码的可见性。尽管当您构建系统的其余部分,并有一些实际的东西作为set方法的副作用进行测试时,这一点最终也会消失。

        3
  •  0
  •   Anirudh    15 年前

    我会谨慎地在类中引入一个只用于测试的公共方法。

    您可以通过多种方式测试:

    反射 :getmodule方法是类中的私有方法(如果“stats”是私有的,这也可以工作),您可以通过反射在测试方法中访问它。这将很好地工作,唯一的问题是,如果您更改私有方法的名称或添加/删除一些变量,您将不会得到任何编译器错误(但是,当然,您的测试将失败,您将很早知道)

    遗传 :GetModule方法可以被保护(只有继承可见),并且测试类可以从主类继承。这样,您的测试类就可以访问这个方法,但这并没有真正暴露在外部世界中。

    断言副作用 :这是您真正思考向系统添加模块意味着什么的地方。如果它会像您所说的那样影响一些“统计信息”,那么您可以编写断言这些统计信息被适当修改的测试。