今天在做项目的时候,发现在测试代码中有一个bad smell。准备测试数据的代码在结构上是类似的,可以用parameterize method的方法进行重构。
为了说明,我就构造了一些简单的示例,示例很简单,只是为了演示重构步骤。
下面的代码都是new了一个person再setName(红色部分代码)。这个步骤是相似的,完全可以抽方法来准备具有名字的person。
@Test
public void should_new_person_with_good_name() {
Person person = new Person();
person.setName("kiwi");
assertThat(person.getName(), is(equalTo("kiwi")));
}
@Test
public void should_new_person_with_bad_name() {
Person person = new Person();
person.setName("sb");
assertThat(person.getName(), is(equalTo("sb")));
}
方法一:抽方法+提取方法参数(不推荐)
1.先抽方法(command + alt + M):
private Person getPerson() {
Person person = new Person();
person.setName("kiwi");
return person;
}
2.提参数(command + alt + P):
private Person getPerson(String name) {
Person person = new Person();
person.setName(name);
return person;
}
然后这样做了以后,代码就变成这B样了,intellij并没有发现这个具有相似结构的代码(红色部分并没有改变):
@Test
public void should_new_person_with_good_name() {
Person person = getPerson("kiwi");
assertThat(person.getName(), is(equalTo("kiwi")));
}
private Person getPerson(String name) {
Person person = new Person();
person.setName(name);
return person;
}
@Test
public void should_new_person_with_bad_name() {
Person person = new Person();
person.setName("sb");
assertThat(person.getName(), is(equalTo("sb")));
}
你需要去手动的找每一个可以用getPerson(String name)的地方,然后再替换,可以想象的是,如果可以替换的地方很多,你就悲催了。
我们希望尽可能的让ide完成这些工作。所以,我推荐使用第二种方法。
方法二:提取局部变量+抽方法
1.提取局部变量(command + alt + V)
@Test
public void should_new_person_with_good_name() {
String name = "kiwi";
Person person = new Person();
person.setName(name);
assertThat(person.getName(), is(equalTo("kiwi")));
}
首先提取变量,将变量移到欲提取的方法体的外部。
2.提取方法(command + alt + M)
这个时候intellij会提示你有重复的代码,选择全部替换,就OK了
@Test
public void should_new_person_with_good_name() {
String name = "kiwi";
Person person = getPerson(name);
assertThat(person.getName(), is(equalTo("kiwi")));
}
private Person getPerson(String name) {
Person person = new Person();
person.setName(name);
return person;
}
@Test
public void should_new_person_with_bad_name() {
Person person = getPerson("sb");
assertThat(person.getName(), is(equalTo("sb")));
}
3.Inline局部变量(optional)
这个时候可以把原来的局部变量inline回去了,如果需要的话。
我使用的intellij是12的community版,使用这样的方法,你就不用再一点点的去找可能重复的地方了。有时候intellij也不是那么的intelligent。