热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

单元测试访问器(getter和setter)-Unittestingaccessors(gettersandsetters)

Giventhefollowingmethods:鉴于以下方法:publicfunctionsetFoo($foo){$this->_foo$foo;

Given the following methods:

鉴于以下方法:

public function setFoo($foo) {
    $this->_foo = $foo;
    return $this;
}

public function getFoo() {
    return $this->_foo;
}

Assuming, they may be changed to be more complex in the future:

假设它们在未来会变得更加复杂:

  • How would you write unit tests for those methods?
  • 如何为这些方法编写单元测试?
  • Just one test method?
  • 只是一个测试方法?
  • Should I skip those tests?
  • 我应该跳过这些测试吗?
  • What about code coverage?
  • 代码覆盖呢?
  • How about @covers annotation?
  • @covers注释呢?
  • Maybe some universal test method to implement in the abstract test case?
  • 在抽象的测试用例中实现什么通用的测试方法?

(I use Netbeans 7)

(我使用Netbeans 7)

This seems like a waste of time, but I wouldn't mind if IDE would generate those test methods automatically.

这似乎是浪费时间,但我不介意IDE自动生成这些测试方法。

To qoute from the comment of Sebastian Bergman's blog:

来自塞巴斯蒂安·伯格曼博客评论的qoute:

(it's like testing getters and setters -- fail!). In any case, if they were to fail; wouldn't the methods that depend on on them fail?

(这就像测试getter和setter一样——失败!)无论如何,如果他们失败了;依赖于它们的方法不会失败吗?

So, what about the code coverage?

那么,代码覆盖率呢?

3 个解决方案

#1


6  

Good Question,

好问题,

i usually try not to test getters&setters directly since i see a greater benefit in testing only the methods that actually do something.

我通常尽量不直接测试getters&setters,因为我发现只测试实际执行的方法有更大的好处。

Especially when not using TDD this has the added benefit of showing me setters that i don't use in my unittests showing me that ether my tests are incomplete or that the setter is not used/needed. "If i can execute all the "real" code without using that setter why is it there."

特别是当不使用TDD时,这有一个额外的好处,就是可以向我显示我在unittests中不使用的setter,从而显示我的测试是不完整的,或者setter是不使用/不需要的。如果我可以执行所有的“真正的”代码而不使用setter,为什么会有它呢?

When using fluent setter i sometimes write a test checking the 'fluent' part of the setters but usually that is covered in other tests.

在使用fluent setter时,我有时会编写一个测试来检查setter的“fluent”部分,但通常在其他测试中会涉及到。

To answer your list:

回答你的列表:

  • Just one test method?
  • 只是一个测试方法?

That is my least favorite option. All or none. Testing only one is not easy for other people to understand and looks 'random' or needs to be documented in a way.

这是我最不喜欢的选择。全部或没有。对其他人来说,只测试一个并不容易理解,而且看起来“随机”,或者需要以某种方式进行记录。

Edit after comment:

编辑后的评论:

Yes, for "trivial" get/set testing I'd only use one method per property maybe depending on the case even only one method for the whole class (for value objects with many getters and setters I don't want to write/maintain many tests)

是的,对于“平凡”的get/set测试,我每个属性只使用一个方法,可能取决于情况,甚至整个类只有一个方法(对于具有许多getter和setter的值对象,我不想编写/维护多个测试)

  • How would you write unit tests for those methods?
  • 如何为这些方法编写单元测试?
  • Should I skip those tests?
  • 我应该跳过这些测试吗?

I wouldn't skip them. Maybe the getters depending on how many you have (i tend to write only getters i actually need) but the task of having a class completely covered shouldn't fail because of getters.

我不会跳过它们。可能getters取决于你有多少个(我倾向于只写我实际需要的getter),但是完全覆盖一个类的任务不应该因为getter而失败。

  • What about code coverage?
  • 代码覆盖呢?
  • How about @covers annotation?
  • @covers注释呢?

With @covers my take is always "use it everywhere or don't use it at all". Mixing the two 'styles' of testing takes away some of the benefits of the annotation and looks 'unfinished' to me.

对于@cover,我的理解总是“在任何地方使用它,或者根本不使用它”。混合使用这两种“风格”的测试会减少注释的一些好处,在我看来是“未完成”的。

  • Maybe some universal test method to implement in the abstract test case?
  • 在抽象的测试用例中实现什么通用的测试方法?

For something like value objects that could work nicely. It might break (or gets more complicated) once you pass in objects / array with type hinting but I'd presonally prefer it over writing manual tests for 500 getters and setters.

对于像value这样可以很好地工作的对象。一旦您传入带有类型提示的对象/数组,它可能会被破坏(或者变得更复杂),但与为500个getter和setter编写手工测试相比,我更喜欢它。

#2


7  

If you do TDD you should write a test for getter and setter. too. Do not write a single line of code without a test for it - even if your code is very simple.

如果您执行TDD,您应该为getter和setter编写一个测试。了。不要在没有测试的情况下编写一行代码——即使您的代码非常简单。

Its a kind of religious war to use a tandem of getter and setter for your test or to isolate each by accessing protected class members using your unit test framework capabilities. As a black box tester i prefer to tie my unit test code to the public api instead of tie it to the concrete implementation details. I expect change. I want to encourage the developers to refactor existing code. And class internals should not effect "external code" (unit tests in this case). I don want to break unit tests when internals change, i want them to break when the public api changes or when behavior changes. Ok, ok, in case of a failing unit test do not pin-point to the one-and-only source of problem. I do have to look in the getter AND the setter to figure out what caused the problem. Most of the time your getter is very simple (less then 5 lines of code: e.g. a return and an optional null-check with an exception). So checking this first is no big deal and not time consuming. And checking the happy path of the setter is most of the time only a little more complex (even if you have some validation checks).

使用一系列的getter和setter进行测试,或者通过使用单元测试框架功能访问受保护的类成员来隔离每个成员,这是一种宗教战争。作为一个黑盒测试人员,我更喜欢将单元测试代码绑定到公共api,而不是将它绑定到具体的实现细节。我期待改变。我希望鼓励开发人员重构现有代码。类内部不应该影响“外部代码”(在本例中是单元测试)。我不想在内部变更时破坏单元测试,我想在公共api变更或行为变更时破坏单元测试。好的,如果单元测试失败了,不要指向唯一的问题源。我必须在getter和setter中查找导致问题的原因。大多数时候,您的getter非常简单(少于5行代码:例如返回和一个异常的可选的空检查)。所以首先检查这个并不重要,也不浪费时间。检查setter的愉快路径大部分时间都只是稍微复杂一点(即使您有一些验证检查)。

Try to isolate your test cases - write a test for a SUT (Subject under test) that validates its correctness without reley on other methods (except my example above). The more you isolate the test, the more your tests spot the problem.

尝试隔离您的测试用例——编写一个测试SUT(被测试的对象),它可以在没有其他方法的情况下验证其正确性(除了上面的例子)。您越是隔离测试,您的测试就越能发现问题。

Depending on your test strategy you may be want to cover happy path only (pragmatic programmer). Or sad pathes, too. I prefer to cover all execution pathes. When i think i discovered all execution pathes i check code coverage to identify dead code (not to identify if there are uncovered execution pathes - 100% code coverage is a missleading indicator).

根据您的测试策略,您可能希望只覆盖“快乐路径”(实用程序员)。或悲伤道。我倾向于覆盖所有执行路径。当我认为我发现了所有执行路径时,我检查代码覆盖率来识别死代码(不确定是否有未发现的执行路径——100%的代码覆盖率是一个错误的指示器)。

It is best practice for black box testers to use phpunit in strict mode and to use @covers to hide collateral coverage.

黑盒测试人员最好在严格的模式下使用phpunit,并使用@cover隐藏附属覆盖率。

When you write unit test your test on class A should be executed independent from class B. So your unit tests for class A should not call / cover method of class B.

当你写单元测试时,你在A类上的测试应该独立于B类来执行,所以你在A类上的单元测试不应该调用B类的方法。

If you want to identify obsolete getter/setter and other "dead" methods (which are not used by production code) use static code analysis for that. The metric you are interested in is called "Afferent coupling at method level (MethodCa)". Unfortunately this metric (ca) is not available at method-level in PHP Depend (see: http://pdepend.org/documentation/software-metrics/index.html and http://pdepend.org/documentation/software-metrics/afferent-coupling.html). If you realy need it, feel free to contribute it to PHP Depend. An option to exclude calls from the same class would be helpful to get a result without "collateral" calls. If you identify a "dead method" try to figure out if it is meant to be used in near future (the counterpart for an other method that has a @depricated annotation) else remove it. In case it is used in the same class only, make it privat / protected. Do not apply this rule to library code.

如果您想识别过时的getter/setter和其他“死”方法(不被生产代码使用),请使用静态代码分析。您感兴趣的度量称为“方法级的传入耦合(MethodCa)”。不幸的是,这个度量(ca)在PHP Depend的方法级别上是不可用的(参见:http://pdepend.org/documentation/softw-metrics/index.html和http://pdepend.org/documentation/softw-metrics/afferent -coupling.html)。如果您确实需要它,请将它贡献给PHP依赖。排除来自同一个类的调用的选项将有助于在没有“附带”调用的情况下获得结果。如果您识别了一个“死方法”,请尝试找出它是否打算在不久的将来被使用(另一个具有@德普化注释的方法的对应方法),那么请删除它。如果只在同一类中使用,请将其设置为私有/受保护。不要将此规则应用于库代码。

Plan B: If you have acceptance tests (integration test, regression test, etc.) you can run that test without running unit tests at the same time and without phpunits strict mode. This can result in a very similar code coverage result as if you had analysed your production code. But in most cases your non-unit tests are not as strong as your production code is. It depends on your discipline if this plan B is "equal enought" to production code to get a meaningful result.

计划B:如果您有验收测试(集成测试、回归测试等),您可以在不同时运行单元测试和没有phpunits严格模式的情况下运行该测试。这可能导致非常类似的代码覆盖率结果,就像您分析了您的产品代码一样。但是在大多数情况下,您的非单元测试不如您的产品代码强大。如果这个计划B与生产代码“相等”以获得有意义的结果,这取决于您的规程。

Further reading: - Book: Pragmatic Programmer - Book: Clean Code

进一步阅读:-书:实用程序员-书:干净的代码

#3


3  

This is a common question but strangely can't find a dupe on SO.

这是一个常见的问题,但奇怪的是却找不到这样的问题。

You could write unit tests for accessors but the majority of practioners do not. i.e. if the accessors do not have any custom logic, I would not write unit tests to verify if field access works. Instead I would rely on the consumers of these accessors to ensure that the accessors work. e.g. If getFoo and setFoo don't work, the callers of these method should break. So by writing unit tests for the calling methods, the accessors get verified.

您可以为访问器编写单元测试,但大多数实践者都不这样做。例如,如果访问器没有任何自定义逻辑,我就不会编写单元测试来验证字段访问是否有效。相反,我将依赖这些访问器的使用者来确保访问器工作。如果getFoo和setFoo不工作,这些方法的调用者应该会中断。因此,通过为调用方法编写单元测试,访问器将得到验证。

This also means that code coverage should not be a problem. If you find accessors that are not covered after all test suites are run, maybe they are redundant / unused. Delete them.

这也意味着代码覆盖率不应该成为问题。如果在运行所有测试套件之后发现访问器没有覆盖,那么它们可能是冗余的/未使用的。删除它们。

Try to write a test that illustrates a scenario where a client will use that accessor. e.g. The below snippet shows how the Tooltip (property) for the Pause Button toggles based on its current mode.

尝试编写一个测试来说明客户端将使用该访问器的场景。下面的代码片段显示了暂停按钮的工具提示(属性)是如何根据当前模式切换的。

[Test]
public void UpdatesTogglePauseTooltipBasedOnState()
{
    Assert.That(_mainViewModel.TogglePauseTooltip, Is.EqualTo(Strings.Main_PauseAllBeacons));

    _mainViewModel.TogglePauseCommand.Execute(null);
    Assert.That(_mainViewModel.TogglePauseTooltip, Is.EqualTo(Strings.Main_ResumeAllBeacons));

    _mainViewModel.TogglePauseCommand.Execute(null);
    Assert.That(_mainViewModel.TogglePauseTooltip, Is.EqualTo(Strings.Main_PauseAllBeacons));
}

推荐阅读
  • Android自定义控件绘图篇之Paint函数大汇总
    本文介绍了Android自定义控件绘图篇中的Paint函数大汇总,包括重置画笔、设置颜色、设置透明度、设置样式、设置宽度、设置抗锯齿等功能。通过学习这些函数,可以更好地掌握Paint的用法。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • Givenasinglylinkedlist,returnarandomnode'svaluefromthelinkedlist.Eachnodemusthavethe s ... [详细]
  • 在本教程中,我们将看到如何使用FLASK制作第一个用于机器学习模型的RESTAPI。我们将从创建机器学习模型开始。然后,我们将看到使用Flask创建AP ... [详细]
  • 1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。 2.对于随机访问get和set,ArrayList优于LinkedList,因为Ar ... [详细]
  • Android 常用工具类源码大全
    Android常用工具类源码大全 ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • Android JSON基础,音视频开发进阶指南目录
    Array里面的对象数据是有序的,json字符串最外层是方括号的,方括号:[]解析jsonArray代码try{json字符串最外层是 ... [详细]
  • ASP.NET2.0数据教程之十四:使用FormView的模板
    本文介绍了在ASP.NET 2.0中使用FormView控件来实现自定义的显示外观,与GridView和DetailsView不同,FormView使用模板来呈现,可以实现不规则的外观呈现。同时还介绍了TemplateField的用法和FormView与DetailsView的区别。 ... [详细]
  • 图像因存在错误而无法显示 ... [详细]
  • 关于如何快速定义自己的数据集,可以参考我的前一篇文章PyTorch中快速加载自定义数据(入门)_晨曦473的博客-CSDN博客刚开始学习P ... [详细]
author-avatar
lovely蓝衣13
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有