我最近正在和一些朋友讨论以下两种方法中哪一种最适合从同一个类中的方法中返回结果或调用同一个类中的方法。
这是一个非常简化的示例。实际上,功能要复杂得多。
例:
public class MyClass
{
public bool FunctionA()
{
return FunctionB() % 2 == 0;
}
protected int FunctionB()
{
return new Random().Next();
}
}
因此,要测试这一点,我们有2种方法。
方法1:使用函数和操作来替换方法的功能。例:
public class MyClass
{
public Func<int> FunctionB { get; set; }
public MyClass()
{
FunctionB = FunctionBImpl;
}
public bool FunctionA()
{
return FunctionB() % 2 == 0;
}
protected int FunctionBImpl()
{
return new Random().Next();
}
}
[TestClass]
public class MyClassTests
{
private MyClass _subject;
[TestInitialize]
public void Initialize()
{
_subject = new MyClass();
}
[TestMethod]
public void FunctionA_WhenNumberIsOdd_ReturnsTrue()
{
_subject.FunctionB = () => 1;
var result = _subject.FunctionA();
Assert.IsFalse(result);
}
}
方法2:使成员成为虚拟成员,派生类,并在派生类中使用“功能和操作”替换功能示例:
public class MyClass
{
public bool FunctionA()
{
return FunctionB() % 2 == 0;
}
protected virtual int FunctionB()
{
return new Random().Next();
}
}
public class TestableMyClass
{
public Func<int> FunctionBFunc { get; set; }
public MyClass()
{
FunctionBFunc = base.FunctionB;
}
protected override int FunctionB()
{
return FunctionBFunc();
}
}
[TestClass]
public class MyClassTests
{
private TestableMyClass _subject;
[TestInitialize]
public void Initialize()
{
_subject = new TestableMyClass();
}
[TestMethod]
public void FunctionA_WhenNumberIsOdd_ReturnsTrue()
{
_subject.FunctionBFunc = () => 1;
var result = _subject.FunctionA();
Assert.IsFalse(result);
}
}
我想知道更好,为什么?
更新:注意:FunctionB也可以是公共的
FunctionB
被设计破坏了。new Random().Next()
几乎总是错的。您应该注入的实例Random
。(Random
这也是一个设计不良的类,可能会导致一些其他问题)
FunctionA
返回布尔值,但仅设置局部变量x
,不返回任何内容。