纯函数
纯函数指的是输出结果仅由输入参数决定,且没有副作用的函数。
函数副作用的表现有以下几点,满足其一即为非存函数
- 导致全局状态突变。即改变某些函数之外定义的字段,数值等。
- 改变输入参数状态。
- 执行任何IO操作,包括使用DateTime.Now, 查询数据库,进行网络调用等。
- 抛出异常(有争议)
如果说某一段代码,你无论如何都想不出怎么才能在单元测试当中覆盖到,那么请思考,是不是代码有问题,也许它被设计为了一个非纯函数。
如何处理非纯函数
我们必须尽量编写纯函数代码,但是在项目当中非纯函数是无法避免,我们可以将非纯函数进行隔离,将其限制在一个最小范围呢,可Mock的范围内。
比如,我们可能会在一个函数当中与当前时间做比较
public bool IsOverdue(DateTime startTime)
{
...
return startTime < DateTime.Now;
}
这个函数显然是无法进行单元测试的。
但是如果我们将获取当前时间的方法拿出去,包装一下,它就是一段可以测试的代码了:
public class ClockWrapper
{
public ClockWrapper(){}
public virtual DateTime CurrentDataTime() => DateTime.Now;
}
public class SomeService
{
private readonly ClockWrapper _clock;
public SomeService(ClockWrapper clock)
{
_clock = clock;
}
public bool IsOverdue(DateTime startTime)
{
...
return startTime < _clock.CurrentDataTime();
}
}
|