说我有这个班:
class MyClass {
private String s;
// more attributes here
public MyClass(String s, /*more constructor params*/) {...}
public String myMethod(String s) {
//complex logic here
}
}
要进行单元测试myMethod()
我需要创建整个对象(需要构造许多参数等),而方法只使用s。
Altenatelly我可以添加一个静态方法:
class MyClass {
private String s;
// more attributes here
public MyClass(String s, /*more constructor params*/) {...}
public String myMethod(String s) {
return myStaticMethod(s);
}
public static myStaticMethod(String s) {
//complex logic here
}
}
现在我可以轻松测试“复杂逻辑”,而无需创建对象。
someStaticMethod(String s)
应该对课程没有副作用。
所以我添加了一个额外的方法只是为了便于测试。
这是一个好习惯吗?
答案 0 :(得分:5)
所以,你已经把一个复杂的方法作为一个对象的一个成员,即使它有 nothing 与该实例没什么关系?
是的,我同意你应该使用不同的设计。 可能是该类中的静态方法,或者它自己的类中的因子。 或它可能是实现“策略”模式的对象的方法。正确的决定取决于变革的可能性。
也许是这样的:
class ComplexLogician {
String myMethod(String a, String b) {
/* Complex logic here. */
}
}
class MyClass {
private String s;
private final ComplexLogician logic;
/* More attributes here... */
MyClass(String s, ComplexLogician logic, /* More parameters... */) {...}
String myMethod(String b) {
return logic.myMethod(s, b);
}
}
答案 1 :(得分:3)
我认为最好不要使方法成为静态,而是在“Before”方法中构造对象一次,该方法将在测试类中的每个测试之前运行。像这样的东西
public class SampleTestSuite {
private MyClass myClass;
@Before
public void startUp(){
myClass = new MyClass();//Will be called before each test method is called.
}
@Test
public void testNavigationSucceeded() {
assert...
}
@Test
public void secondTest() {
assert...
}
@After
public void tearDown() {
}
}
答案 2 :(得分:2)
如果方法可以是静态的,那么它应该是静态的,无论你需要它进行测试还是其他什么。您可以在Eclipse中打开警告。 Eclipse会向您发出警告,然后提供有关非静态方法的警告。
答案 3 :(得分:2)
更改生产代码并暴露其“胆量”以便您可以对其进行测试是一种非常糟糕的做法。它破坏了封装,如果你的代码首先是不可测试的,那通常意味着它需要重构。
您希望以静态方法移动的“复杂逻辑”肯定会有利于正确的OO处理。 让一个专家级来处理那个逻辑或一组类,将它们注入到MyClass
通过界面,单独的关注点,你的测试将变得更加容易。
更好的是,使用模拟框架开始测试(TDD),这将有机地推动一个好的设计,而不需要静态方法或类似的黑客。
示例:假设您的MyClass
需要对其中一个参数进行大量转换(在您的情况下,String s
才能使用它。所以您想要提取将处理转换为静态方法?而不是向您的类添加一个依赖项,例如,StringTransformer
(相应地重命名),它是您想要的实际实现的接口。拥有方法transform(String s)
在变压器中,它将包含您想要的逻辑。然后使用常规方法测试您的实现,完成工作。并且您实际上使您的设计更好。
答案 4 :(得分:1)
我经常将类的一部分功能写为包受保护的静态方法,并根据需要传入字段值。它允许您全面测试功能,而无需将其拆分为单独的类。它可以提供全面的测试覆盖,而不会增加太多的复杂性。
答案 5 :(得分:0)
一般来说,暴露任何超出类所期望功能的功能并不是一种好习惯。由于其他客户端可能已经开始使用代码,因为这种方法是公开的,因此这将阻碍远离该逻辑。另一个选择是使函数受到保护,以便在测试层次结构中的同一个包中,可以编写测试用例。但是,我会选择通过形成一个基础对象来编写测试用例,并继续更改其中的输入和输出集,而不是使用这些解决方法。
答案 6 :(得分:0)
如果您只测试静态方法,那么您将保留实例方法。您可以改为更改实例方法,以便对其进行测试。如果您在此处发布特定案例的更多详细信息或作为新问题,我相信有人会帮助您使其可测试。