I simply want to know if there is a way to mock an array of FTPFile. I am trying to pass as a parameter a fake FTPFile[] to the function I want to test:
protected void indexFolder(FTPClient, FTPFile[], File, FTPFolderAssetSource);
I am using FakeFtpServer to fake, as the name says, my ftp server. This library permit to fake the ftp content in this way:
fileSystem = new WindowsFakeFileSystem();
DirectoryEntry directoryEntry1 = new DirectoryEntry("c:\\");
directoryEntry1.setPermissions(new Permissions("rwxrwx---"));
directoryEntry1.setOwner(USER1);
FileEntry fileEntry1 = new FileEntry("c:\\data\\file1.txt", CONTENTS);
fileEntry1.setPermissionsFromString("rw-rw-rw-");
fileEntry1.setOwner(USER1);
fileEntry1.setGroup(GROUP);
fileSystem.add(directoryEntry1);
fileSystem.add(fileEntry1);
ftp = new FakeFtpServer();
ftp.setFileSystem(fileSystem);
Now, how can I use fileSystem to test my function who require FTPFile[] as parameter?
There is nothing specialy about the FTPFile
class which would prevent mocking. Unfortunately, using Mockito, you can not mock arrays, as they are final.
This sample code should demonstrate the problem:
import static org.mockito.Mockito.*;
import org.junit.Test;
public class TestMockArrays {
interface Animal {
String getName();
}
@Test
public void testMockArray() {
final Animal[] mockArray = mock(Animal[].class);
when(mockArray[0].getName()).thenReturn("cat");
when(mockArray[1].getName()).thenReturn("dog");
when(mockArray[2].getName()).thenReturn("fish");
print1st3(mockArray);
}
public static void print1st3(final Animal[] animals) {
System.out.println(animals[0].getName() + " " + animals[1].getName() + " " + animals[2].getName());
}
}
Run it, and you'll see it results in an error message which makes explicit the problem:
org.mockito.exceptions.base.MockitoException: Cannot mock/spy class [LTestMockArrays$Animal;
Mockito cannot mock/spy following: - final classes - anonymous classes - primitive types
The easiest solution is to use an extension to Mockito like Powermock which gets around certain restrictions to Mockito's mocking ability by using bytecode manipulation. Then you could create the mock array by adding the following annotations to your junit test class:
@RunWith(PowerMockRunner.class) // Need to run with Powermock runner
@PrepareForTest(FTPFile[].class) // We prepare FTPFile[] class for test because it's final
then in your test method you would create Mockito mock as normal:
FTPFile[] mockFTPFiles = mock(FTPFile[].class);