单元测试(unit testing):
单元测试是指编写代码来专门测试其他代码。单元测试能让随时随地的重构成为可能。
1、布置、动作和断言(布置测试前置条件、执行要测试的动作、断言所预期的行为 AAA)
1.布置测试前置条件(Arrange):当要测试目标动作时,需要先搭建测试场景的上下文。
2.执行可测试的动作(Act):执行要测试的方法。每个测试的动作阶段值应该与测试目标系统交互一次,比如只调用一个方法或只使用一次属性的存取。
3.断言所期望的行为(Assert):判断测试目标系统的状态值与期望得到的结果是否相同。
4.运行测试:使用单元测试运行器运行所编写的单元测试。
2、测试驱动开发(Test-Driven Development TDD):
先编写测试代码,然后才编写产品代码。产品代码中的每个方法都需要经过一次失败的测试,这次失败的唯一原因就是产品的具体实现代码还不存在。
1、失败、成功、重构(red、green、refactor):
针对测试目标系统的期望行为编写一个失败的测试。、
给测试目标系统添加恰当的实现来让新加入的测试通过,且不影响所有已存在的测试。(最小代码改动,测试成功后根据期望的行为添加其他单元测试,然后最小代码改动使测试通过)
看看测试目标系统的设计或代码质量是否有改进的机会,如果有则立刻重构。
3、更复杂的测试:
测试时,当需要实现一个接口时,可以在单元程序集中创建一个接口的临时实现类。
使用模拟测试Moq模拟框架(或称Moh-kyoo 或Mok):new Mock<IInterface>();
进一步测试:异常测试[ExpectedException(typeof(ArgumentNullException))],测试当出现异常时是否通过。[ExpectedException(typeof(ServiceException))],测试是否捕获到了原始异常信息。
测试初始化:
同目标类一样,测试类也可以定义编写公共的初始化方法(注:方法需要[TestInitialize]修饰)
重构(refactoring):
重构时一个改善现有代码设计的过程。给变量更名是一次重构,必要时将用户界面层逻辑和域逻辑分开是影响巨大的架构重构。(重构只改变代码的布局而不是输出)
1、更改已有代码:
用常量替代魔法数,即将代码中的数字使用const修饰的常量来替代。常量的命名用来解释这个常量所代表的信息。
用多形性替代条件表达式,在Switch分类时,使用提取共同方法,使用多态的方式来将Switch分类拆分开来,增加可读性以及兼容性。
使用工厂方法替代构造函数,使用方法来创建子类对象,返回新创建的子类对象(Static 函数,函数中创建子类独享,返回父类引用)。
使用工厂类替代构造函数,创建一个接口,接口的方法实际上与工厂方法一样,但是是一个实例方法。(接口的实现需要知道所有的子类的类型)
代码味道:拒绝继承
子类会直接拒绝实现接口的方法而不是忽略他,而接下来的重构方式会拒绝实现整个接口。
用委托替代继承
使用接口来替代继承