在之前的的TDD案例-FizzBuzz文章中,我们介绍了如何以TDD的方式,通过5个测试用例,来驱动我们实现了FizzBuzz。
本文将继续对FizzBuzz的简要实现进行重构。
1. FizzBuzz实现的重构
这是之前的一个简单实现。
package com.github.tdd;
public class FizzBuzz {
public String say(int i) {
if(i%15==0)
return "FizzBuzz";
if(i%3==0)
return "Fizz";
if(i%5==0)
return "Buzz";
return Integer.toString(i);
}
}
FizzBuzz的需求相对来说是非常简单的,此处我们使用了3个if判断来实现略显多余。因此,可以进行一下优化。
package com.github.tdd;
public class FizzBuzz {
public String say(int i) {
String result="";
if(i%3==0)
result+="Fizz";
if(i%5==0)
result+="Buzz";
return result.isEmpty() ? Integer.toString(i):result;
}
}
对于既能被3整除,也能被5整除的场景,我们可以通过上述实现来进行简化,从而去掉一个if判断。
通过执行原先的测试用例,我们可以放心地对代码进行重构了。
image.png
2. FizzBuzz测试用例的重构
通过观察之前编写的测试用例,可以看出这些用例在格式上是相同的,只是输入和预期结果不同,目前的写法是存在一定的冗余。
@Test
public void TestTwoIsTwo() {
assertThat(fizzBuzz.say(2)).isEqualTo("2");
}
@Test
public void TestThreeIsFizz() {
assertThat(fizzBuzz.say(3)).isEqualTo("Fizz");
}
熟悉Junit测试框架的读者都了解参数化测试的功能。因此,我们可以使用Junit5来重构之前的5个用例。
package com.github.tdd;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import static org.assertj.core.api.Assertions.assertThat;
public class TestFizzBuzzUsingParams {
FizzBuzz fizzBuzz = new FizzBuzz();
@ParameterizedTest(name = "the result is ''{1}'' when say ''{0}''")
@CsvSource(
{
"1,1",
"2,2",
"3,Fizz",
"5,Buzz",
"15,FizzBuzz"
}
)
public void test_should_pass(int what, String result) {
assertThat(fizzBuzz.say(what)).isEqualTo(result);
}
}
来看一下执行结果
image.png
3. 增加异常处理
对于小于等于0的入参,我们抛出一个RuntimeException。先写一个用例
@Test
public void test_shouldThrowException() {
assertThatThrownBy(() -> fizzBuzz.say(0))
.isInstanceOf(RuntimeException.class)
.hasMessage("should > 0");
}
然后在say方法中增加如下一行来实现它。
if(i<=0)
throw new RuntimeException("should > 0");
网友评论