JUnit: checking if a void method gets called
37,567
Solution 1
With Mockito, you can verify whether a method is called at least once/never.
See point 4 in this page
eg:
verify(mockedObject, times(1)).onChange(); // times(1) is the default and can be omitted
Solution 2
Here is a simple modification for your test.
@Test
public void testPropertyFileWatcher() throws Exception {
final File file = new File("testfile");
file.createNewFile();
final AtomicBoolean hasCalled = new AtomicBoolean( );
PropertyFileWatcher propertyFileWatcher =
new PropertyFileWatcher(file)
{
protected void onChange ( final File localFile )
{
hasCalled.set( true );
assertEquals( file, localFile );
}
}
Timer timer = new Timer();
timer.schedule(propertyFileWatcher, 2000);
FileWriter fw = new FileWriter(file);
fw.write("blah");
fw.close();
Thread.sleep(8000);
// check if propertyFileWatcher.onChange was called
assertTrue( hasCalled.get() );
file.delete();
}

Comments
-
nkr1pt over 2 years
I have a very simple file watcher class which checks every 2 seconds if a file has changed and if so, the
onChange
method (void) is called. Is there an easy way to check if theonChange
method is getting called in a unit test?code:
public class PropertyFileWatcher extends TimerTask { private long timeStamp; private File file; public PropertyFileWatcher(File file) { this.file = file; this.timeStamp = file.lastModified(); } public final void run() { long timeStamp = file.lastModified(); if (this.timeStamp != timeStamp) { this.timeStamp = timeStamp; onChange(file); } } protected void onChange(File file) { System.out.println("Property file has changed"); } }
Test:
@Test public void testPropertyFileWatcher() throws Exception { File file = new File("testfile"); file.createNewFile(); PropertyFileWatcher propertyFileWatcher = new PropertyFileWatcher(file); Timer timer = new Timer(); timer.schedule(propertyFileWatcher, 2000); FileWriter fw = new FileWriter(file); fw.write("blah"); fw.close(); Thread.sleep(8000); // check if propertyFileWatcher.onChange was called file.delete(); }
-
Kartik over 12 yearsYou can use any mocking framework and not just mockito. Take a look at EasyMock or jMock and pick what you like. The rule of thumb of writing unit tests is that you should only mock the objects that you can control. In other words, the mock objects should be made available to the class under test using constructor arguments/setters or parameters to your method under test. By this logic, you cannot mock static invocations, final or private, or "new" objects created inside the method of the class under test.
-
nkr1pt over 12 yearsI really like this solution because it doesn't add a dependency to a mocking framework; however mocking frameworks are a necessity for unit testing; that's why I'm accepting the mocking suggestion as the accepted answer to my question.
-
nkr1pt over 12 yearsAny idea how you can do it in EasyMock? I find the documentation lacking on this. When I create a mock for PropertyFileWatcher like this: PropertyFileWatcher propertyFileWatcher = createMockBuilder(PropertyFileWatcher.class).withConstructor(file).createMock(); and record the expected call to onChange and replay: propertyFileWatcher.onChange(file); replay(propertyFileWatcher); the onChnage method is called right away and info is printed to sysout, but I would just like to verify IF that method was called or not
-
Alexander Pogrebnyak over 12 years@nkr1pt. Definitely go with a reputable mocking framework. If you are not confined to 1.4 version of JDK, take a look at jMock.
-
Jordi P.S. over 10 yearsDon't use mockito being able to do the AtomicBoolean solution.
-
Tony over 8 yearsThe second link is not up to date. you can see this page : Mockito documentation
-
kaybee99 about 6 yearsMost of these links are broken. Please paraphrase/quote content directly in the answer to avoid redundancy.
-
Sipty over 5 yearsJust letting you know the link is broken.