问题
My program has a daily routine, similar to an alarm clock event. Say, when it's 2pm(The time is the system time in my pc), do something for me.
What I want to do is to speed up the testing period(I don't really want to wait 4 days looking at the daily routine and check errors.) I read on wiki of Mock object, the writer DID mention alarm clock program. I was so happy to see but still, don't know how to do it.
I am new to Mock Object, and I am programming in Java. So JMock or EasyMock(or any similar) might okay to me.
Thanks
回答1:
Whenever you need to get the current time, don't use the system clock directly - use an interface such as:
public interface Clock
{
long currentMillis();
}
You can then implement this with a system clock for production, and pass in a fake for tests, where you can set the fake to whatever time you want.
However, you'll also need to mock out whatever's driving your system - are you explicitly waiting for a particular time, or does something else call your code?
回答2:
I do have to apologize since you've asked about java and I'm out to lunch when it comes to java, but one solution is to Mock the DateTime object and set it for the desired time.
In .NET it would look something like this:
public static class SystemTime
{
public static Func<DateTime> Now = () => DateTime.Now;
}
SystemTime.Now = () => new DateTime(2000,1,1);
From: Dealing With Time In Tests
... [A]n alarm clock program which causes a bell to ring at a certain time might get the current time from the outside world. To test this, the test must wait until the alarm time to know whether it has rung the bell correctly. If a mock object is used in place of the real object, it can be programmed to provide the bell-ringing time (whether it is actually that time or not) so that the alarm clock program can be tested in isolation.
This Alarm Clock you're referencing is giving an example of mocking an object. It isn't actually an object you can use from the mock framework.
回答3:
Basically what you do in the test is fake the clock events. Exactly how depends somewhat on the design, and how you are waiting for the event, but to keep it simple (if not pure) my approach would be to have a method that is called when the time event is triggered, and then test both sides of that.
First is to test calling the method and seeing that the timed event does what you expect. Then mock that class (with JMock the preferred way is to make it an interface and have your calling method implement that interface).
You then pass the mock to the class that handles the timing. Here again, I would abstract out the threading/triggering issues (such as checking the system clock and starting the thread) and have mocks return values that essentially run the event right away.
Then keep the real code that actually reads the system clock and starts the thread as small as possible, and that will be the area that isn't under unit test.
回答4:
Mocking relates to unit testing. For the functionality you are describing I would separate the trigger (in your case the alarm clock event) from the process (whatever it is your 'daily routine' is doing) and unit test the process functionality.
Then direct your attention to the scheduling code that will invoke your process functionality. I would recommend using something like Quartz for this but if you are going to role-your-own the unit test for it can work with the actual system clock provided you assign the trigger time based on the current value of the system clock as all you will be testing for is that the trigger event occurs.
来源:https://stackoverflow.com/questions/1143322/how-to-use-mock-object-mimicing-a-daily-routine-program