FizzBuzz Rules Overview0:00
Next up is the obligatory fizzbuzz kata, and I think you'll find this is quite a bit easier, especially now that we're more seasoned. So let's go over the rules. We will convert a number for fizzbuzz. Multiples of 3 should print fizz instead of the number. So if I give it the number 3 to convert, it'll return fizz. If I give it 6, that returns fizz. 9. You get the idea. Okay, multiples of 5 should print or return buzz.
Make Tests Readable1:20
But there is one downside in that your tests no longer provide a form of documentation. You can't read the test to figure out how the class should work. It just shows you all of the expectations. So why don't we tweak it a little bit? I would like my test class to read almost the same as our notes here. These are the requirements. So we'll start with the first one. For multiples of 3, print fizz instead of the number. So how about this? It returns a fizz for multiples of 3.
Create FizzBuzz Converter1:46
So how about this? It returns a fizz for multiples of 3. Okay, so I think this can be a static method, and if not, we'll switch it out. But I'm not sure we're doing anything that would warrant it not being a static method. So if I convert for 3, that should equal fizz, right? So we give that a run, and of course it fails because there is no class called FizzBuzz. So I'm going to create that now. It's in the app namespace, and that will go in our source directory. All right, switch back, pull it in, and run it again. All right, now there's no method convert.
All right, switch back, pull it in, and run it again. All right, now there's no method convert. So let's add that method automatically, and that will accept a number. Okay, run it again, and it fails because we expected fizz. All right, let's slime it. Ta-da! It works. All right, let's add another one. So in this case, yeah, we could add more methods, but why don't we do sort of like an inline data provider?
Add Data-Driven Fizz Tests2:45
So in this case, yeah, we could add more methods, but why don't we do sort of like an inline data provider? So why don't we say for each numbers that are divisible by 3, so 3, 6, 9, and 12 as number, let's write an assertion like this. So convert the number, and if I give it a run, it's still going to pass because fizz is the only thing we are returning. That's okay, we're going to refactor in a bit. It returns buzz for multiples of 5. So if we have 5, 10, 15, well, we know that's going to return something different, so let's skip over it for the time being.
Implement FizzBuzz Case4:14
So now I think we'll get the exact same thing, but now it's becoming a little more clear what the rules are. All right, let's continue on. It returns fizzBuzz for multiples of 3 and 5. So if you give it 15, 30, 45, 60, that'll return fizzBuzz. So we give that a run, and of course it fails. So let's say at the top here, we'll start, you could say if the number is divisible by 3 and 5, then return fizzBuzz, and I bet that works. Yep, and if we run all of the tests, that works as well.
So if I run our tests again, even though we've commented this out, it still passes. Think about it. Let's say the number you give us is 15. All right, we start with an empty string. Is 15 divisible by 3? Yes. So now result is fizz. Then we move on. Is 15 divisible by 5? Yes.
Refactoring Simplicity Guidance6:48
And believe it or not, that's it. This is a really easy one, but there are a couple of things to be aware of. So notice when I look at the test now, because we didn't reach for a data provider, now this reads like documentation. I can look at this Test class and basically understand how fizzbuzz works. Okay, it returns fizz for multiples of 3, buzz for multiples of 5, fizzbuzz for multiples of both. Otherwise, it returns the original number. I can instantly learn the rules by looking at the Test class. Next, in situations where the algorithm, if you want to call it that, is so simple,
I can instantly learn the rules by looking at the test class. Next, in situations where the algorithm, if you want to call it that, is so simple, don't complicate it any more than you need to. So for example, yes, you could extract this to a method called isDivisibleBy3. And you could extract this to a method. You know, we often think we're being good programmers by extracting this stuff, isDivisibleBy5. And yes, everything still works. But I want you to ask yourself, is this better than you had before? And the answer to that question is, well, it depends on why you performed the extraction.
And is it really easier for me to take in versus that? I don't think so. Keep it simple. However, that being said, there are situations where a conditional is so confusing, it really does make sense to extract a method. And we've done that very thing in this series a number of times. As with everything, rely on your own judgment. And always ask that question after you perform a refactor, is this better than what I had before? And if the answer is no, undo it.
