2013-04-10 77 views
4

在接受记者采访时,有人问我这个问题:“你怎么做代码很难进行单元测试?”最后我喃喃自语的东西写一个紧密耦合的代码。任何人都可以告诉我什么是这个问题的正确答案/方法?编写代码,这是很难进行单元测试

回答

4

看看Mishko的Guide: Writing Testable Code,将许多这些缺陷介绍到您的代码中,最终会得到无法测试的代码。

例如:

  • 做尽可能多,你可以在构造函数中,通过创建到处方法的长链调用
  • 使用的单身启动线程,使用循环和IFS得墨忒耳
  • 破法,他求的依赖,看看他们在静态提供商
  • 与2k行的代码创建全能类
+0

米斯科的博客是一个救世主!我分享了相同的链接;) – 2013-04-10 05:25:26

+0

我不同意2K行代码点。 – 2013-04-10 05:27:24

+1

2K是上帝级的?那么我该怎么处理15K +的课程 - 是那些宇宙课程? – dascandy 2013-04-10 05:53:31

1
  • 使用new操作类需要创建依赖自己就足够了!这意味着紧密耦合的代码是您的答案。
  • 不遵循SOLID principles的代码。

所以在测试中,您将无法使用Mock对象,因为您正在自己创建依赖关系并对关系进行硬编码。

With dependency injection您可以使用多态行为,因此调用构造函数或方法中传递给它的依赖关系的某个方法的类不需要知道具体类型。所以在测试中你可以传递一个模拟对象,你将能够轻松地测试你的类。

Misko's Writing testable code解释我们如何擅长写作的代码是不可测试以及如何解决它。

实施例(JAVA):

//hard to unit test this code as testing class A also requires that ClassB should work properly 
//What is ClassB does some I/O or DB operations. This makes unit test a integration test 
class classA{ 
    ClassB b = new ClassB(); //Creating concrete dependencies 

} 

interface B{ 
    //implemented by Class B and your mock class that you create for testing 
} 

class ClassA{ 
    private B b; 

    //Here you can use mocking framework or create a mock class yourself and pass that as argument 
    //So the mock class will not do any DB or I/O and makes this unit test 
    public classA(B b){ 
     this.b = b; 
    } 
} 
2

好一些答案可能是

  • 它访问数据库
  • 根据系统日期时间
  • 一个代码,其表现一个代码的代码其确实在同一梅索德多于一个的功能性(单位)
  • 一个代码有很多coditio的最终行为取决于另一个不可读的代码

并且在任何代码中难以/不可能模拟环境以使其表现出需要测试的方式。

+0

访问数据库的代码不再是单元测试。 – 2013-04-10 05:22:41

+0

@NarendraPathai代码没有单元测试,测试代码的测试是单元测试,不应该测试访问数据库的单元,因此除了逻辑外还有一个访问数据库的逻辑组件,它是最不可能的,应该是不是单元测试 – CloudyMarble 2013-04-10 05:27:38

+0

我的意思是一个测试,试图测试一个类访问数据库将不再是一个单元测试,应该被称为*集成测试*。 – 2013-04-10 05:30:03

1

这是一个很好的答案。紧密耦合的代码对于单元测试是非常困难的(并且可能不应该进行单元测试 - 应该首先对其进行重新考虑),因为根据定义,单元测试只能测试某个特定的单元。所有对数据库或系统其他组件的调用都应该从单元测试中避免,因为它们违反了这个规定。

虽这么说,你也可以提,集成测试是很好用的依赖,甚至是基于行为动作测试更大的代码或代码耦合。您可以构建一个集成测试套件,用于测试您的REST API,它具有许多依赖关系,甚至可以跨越许多技术和多种编程语言。

此外通过设计没有考虑或不使用一个体面设计图案可以导致极耦合或相关的代码可以是困难的或不可能的单元测试,而无需重新因式分解或重新写入。然后你可以谈论TDD(测试驱动开发http://en.wikipedia.org/wiki/Test-driven_development)或BDD(行为驱动开发http://en.wikipedia.org/wiki/Behavior-driven_development),这迫使你从设计测试套件开始并从那里开始工作。

0

很难分开的代码 - 多个职责之间分散了多个职责,但没有任何职责完全承担任何责任

代码非常复杂 - 请尝试500行的平均状态机的if/then/else炸弹。

代码在给定的领域非常强大,数学就是一个明显的例子。采用傅里叶变换函数并添加一个单元测试,显示全零变换为全零。 100%的覆盖率,但没有真正的测试。

与外部相关性密切相关的代码错综复杂地链接在一起。

代码与巨大的接口,做多件事情。

相关问题