Skip to content

Fix files delete tests - #5465

Open
sumittlearnbay wants to merge 3 commits into
spring-projects:mainfrom
sumittlearnbay:fix-files-delete-tests
Open

Fix files delete tests#5465
sumittlearnbay wants to merge 3 commits into
spring-projects:mainfrom
sumittlearnbay:fix-files-delete-tests

Conversation

@sumittlearnbay

Copy link
Copy Markdown

Thank you for taking time to contribute this pull request!
You might have already read the contributor guide, but as a reminder, please make sure to:

  • Rebase your changes on the latest main branch and squash your commits
  • Add/Update unit tests as needed
  • Run a build and make sure all tests pass prior to submission
  • Sign-off commits according to the Developer Certificate of Origin

For more details, please check the contributor guide.
Thank you upfront!

Signed-off-by: sumittlearnbay <sumit.learnbay@gmail.com>
Signed-off-by: sumittlearnbay <sumit.learnbay@gmail.com>
@sumittlearnbay
sumittlearnbay force-pushed the fix-files-delete-tests branch from 322ac5b to 3fe9c2b Compare July 21, 2026 15:06
@noojung

noojung commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

I had the same problem on Windows 11.

After looking into the root cause, I found that the following line was written incorrectly in the first place:

when(mocked.delete()).thenReturn(false);

According to the Mockito javadoc, it is recommended to always use doReturn() for spies:
(Related link: https://javadoc.io/doc/org.mockito/mockito-core/latest/org.mockito/org/mockito/Mockito.html#spy(T))

   List list = new LinkedList();
   List spy = spy(list);

   //Impossible: real method is called so spy.get(0) throws IndexOutOfBoundsException (the list is yet empty)
   when(spy.get(0)).thenReturn("foo");

   //You have to use doReturn() for stubbing
   doReturn("foo").when(spy).get(0);

However, even if you update the code to use doReturn(), the test still fails (and now it fails on macOS as well):

//		when(mocked.delete()).thenReturn(false);
		doReturn(false).when(mocked).delete();

This is because, ItemWriter's close() method actually deletes the file using Files.delete().

Therefore, in my opinion, instead of acquiring a lock with RandomAccessFile, mocking Files.delete() would be a better approach.

Here is my sample code:

	@Test
	void testFailedFileDeletionThrowsException() {
		writer.setShouldDeleteIfEmpty(true);
		writer.open(executionContext);

		try (MockedStatic<Files> mocked = Mockito.mockStatic(Files.class, Mockito.CALLS_REAL_METHODS)) {
			mocked.when(() -> Files.delete(any())).thenThrow(new IOException("Failed to delete file"));

			ItemStreamException exception = assertThrows(ItemStreamException.class, writer::close,
					"Expected exception when file deletion fails");

			assertEquals("Failed to delete empty file on close", exception.getMessage(), "Wrong exception message");
			assertNotNull(exception.getCause(), "Exception should have a cause");
		}
	}

@sumittlearnbay

Copy link
Copy Markdown
Author

Thank you for the explanation and suggestion.

I updated both AbstractFileItemWriterTests and StaxEventItemWriterTests to mock Files.delete() using MockedStatic instead of File.delete(), following your recommendation. I verified the updated tests locally and pushed the changes to this PR.

Please let me know if you see anything else that should be adjusted.

@noojung

noojung commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Oh, and it's no big deal, but the filename AbstractFileItemWriterTest.java is missing an 's'.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants