|
How do you test code that relies on the current time in C#/Java. I've seen a couple solution. Injecting some type of abstract Clock/SystemClock everywhere being common. C#'s lambda's let you do something nicer, like: class SystemTime
{
public Func<DateTime> Now => () = DateTime.Now;
}
Ultimately though, you're having to work around the fact that Java and C# are class-oriented, rather than object-oriented. Classes are useful - they serve as a template for your object, but in most (all?) dynamic languages, the class itself is a living, breathing, modifiable, runtime object.What does all this mean? How do you get the current time in a testable manner in Ruby? Use Time.now. You don't implement patterns or change your code. You don't fear the evil static..because really, it isn't a static - we don't even call it a static. It's just another method on another class, which we can rewrite at runtime as need be. How do you stub it? Well, using a mocking framework: Time.stub!(:now).and_return(Time.local(2011, 5, 3, 0, 1, 22)) The mechanics of how this is internally done isn't too complicated once you know about Ruby's metaprogramming (which probably takes around the same amount of time as getting familiar with C# or Java's reflection capabilities). I know, it's a simple example. But it's surprisingly common. And I find it a little ridiculous that to get the time, we need to start creating interfaces and injecting parameters. While C#'s lambda's largely solve this problem, move to something just slightly more complicated, and you're back at square one. I dunno, not sure if that explained it without being condescending. I'm tired...that stub is actually returning a pretty accurate time for me. |
Essentially the benefit we're pushing here is cheap decoupling where in static languages you're having to set this kind of arduous plumbing up yourself, aye?