今天在做項目的時候,發現在測試代碼中有一個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。