我正在构建一个类库,它将有一些公共和私有方法。我希望能够对私有方法进行单元测试(主要是在开发过程中,但也可以用于将来的重构)。
正确的做法是什么?
我正在构建一个类库,它将有一些公共和私有方法。我希望能够对私有方法进行单元测试(主要是在开发过程中,但也可以用于将来的重构)。
正确的做法是什么?
当前回答
JAVA语言
在这里,您可以使用模拟行为覆盖测试类的特定方法。
对于下面的代码:
public class ClassToTest
{
public void methodToTest()
{
Integer integerInstance = new Integer(0);
boolean returnValue= methodToMock(integerInstance);
if(returnValue)
{
System.out.println("methodToMock returned true");
}
else
{
System.out.println("methodToMock returned true");
}
System.out.println();
}
private boolean methodToMock(int value)
{
return true;
}
}
测试类将是:
public class ClassToTestTest{
@Test
public void testMethodToTest(){
new Mockup<ClassToTest>(){
@Mock
private boolean methodToMock(int value){
return true;
}
};
....
}
}
其他回答
在我看来,你应该只对类的公共API进行单元测试。
为了对方法进行单元测试,将其设为公共,会破坏封装,暴露实现细节。
一个好的公共API解决了客户端代码的直接目标,并且完全解决了这个目标。
将它们声明为内部的,然后使用InternalsVisibleToAttribute允许单元测试程序集看到它们。
MbUnit有一个很好的包装,叫做Reflector。
Reflector dogReflector = new Reflector(new Dog());
dogReflector.Invoke("DreamAbout", DogDream.Food);
您还可以从属性中设置和获取值
dogReflector.GetProperty("Age");
关于“私人测试”,我同意…在完美的世界里。做私有单元测试是没有意义的。但在现实世界中,您可能最终希望编写私有测试,而不是重构代码。
这里有一个例子,首先是方法签名:
private string[] SplitInternal()
{
return Regex.Matches(Format, @"([^/\[\]]|\[[^]]*\])+")
.Cast<Match>()
.Select(m => m.Value)
.Where(s => !string.IsNullOrEmpty(s))
.ToArray();
}
下面是测试:
/// <summary>
///A test for SplitInternal
///</summary>
[TestMethod()]
[DeploymentItem("Git XmlLib vs2008.dll")]
public void SplitInternalTest()
{
string path = "pair[path/to/@Key={0}]/Items/Item[Name={1}]/Date";
object[] values = new object[] { 2, "Martin" };
XPathString xp = new XPathString(path, values);
PrivateObject param0 = new PrivateObject(xp);
XPathString_Accessor target = new XPathString_Accessor(param0);
string[] expected = new string[] {
"pair[path/to/@Key={0}]",
"Items",
"Item[Name={1}]",
"Date"
};
string[] actual;
actual = target.SplitInternal();
CollectionAssert.AreEqual(expected, actual);
}
这里有一篇关于私有方法单元测试的好文章。但是我不知道哪个更好,是让你的应用程序专门为测试而设计(就像只为测试而创建测试)还是使用反射来测试。 我敢肯定大多数人都会选择第二种方式。