Lesson 16 of 21
Faking Futures
How do you deal with objects being creating directly inside legacy code (external link, opens in new tab)? We can refactor that!
In this lesson
Roy Osherove discusses an exercise with a login manager that creates a new slow logger, where the test has to prove that the logger's write method is called. He compares extracting a protected method that returns the slow logger, which needs a fake (external link, opens in new tab) subclass of it, with extracting the whole call into a protected method, which he usually prefers as simpler.
Transcript
[00:03] (external link, opens in new tab) So this is let's talk for a second about the requirement about login manager with future. Now login manager with future you you have a call to new slow logger and the requirement is that you prove that it calls the new slow logger with the method write because this is legacy code (external link, opens in new tab). Now we have two choices when it comes to new. We can either refactor just this part of the call or we can refactor the whole call.
[00:34] (external link, opens in new tab) If we refactor just the call to slow logger to create the new one we set a method called get slow logger and make it protected. What happens now? We have to return something that looks like a slow logger. In our test, we'd have to create a class that inherits from slow logger, overrides whatever is needed, and then returns that. That's possible, but that's more complicated. We also will inherit anything from slow logger that we don't override.
[01:04] (external link, opens in new tab) That could mean that maybe it uses something underneath we don't control. So, it's more complicated to do this than to say protected void. or sorry let's undo this whole thing and say extract this whole line say call new logger make that protect it and make this a variable
[01:40] (external link, opens in new tab) So here we might say text like this. Now, this is very much like what we did before with static logger. It's a much simpler way to check that something was called. So, we can either choose to fake one level below and return the object or we can choose to just call the object in the simplest way possible (external link, opens in new tab) and prove that that happened. I usually choose this way
[02:11] (external link, opens in new tab) Rather than return a slow log or other unless I really have no choice and I only have no choice when I need a mock object (external link, opens in new tab) to be called and I have no way to inject the mock object. For example, if I need to check that not a static logger was called but that a new slow logger was called. Right? This is the only way I either have to do this or I have to return an instance. And this this is actually the the simplest way that I know how to do it.