Reputation: 1595
I am updating a few tests. The Before gets the sftp session. For this, the username and password have been hardcoded in the properties file. Due to security reasons, the password cannot be checked in and has to be blanked out. However the unit test fails at
private DefaultSftpSessionFactory sftpClientFactory;
private SftpSession sftpSession;
@Before
public void setup() {
sftpSession = sftpClientFactory.getSession();
}
This step fails with "either a password or private key is required".I would like to get a mock session, so that I dont have to provide a password.
Upvotes: 4
Views: 8387
Reputation: 31
As mentioned by jannis here a better alternative is to use a fully functional test SFTP environment.
Why? Because mocking the logic requires a lot of boilerplate and does not allow one to fully test the application and its moving parts. Luckily, the test containers support is mature enough and can be used for your case.
The SFTP test container in a SpringBoot environment can be easily set up as follows:
@SpringBootTest
class SshClientDemoApplicationTests {
@Container
static final GenericContainer<?> SFTP = new GenericContainer<>("atmoz/sftp:latest")
.withExposedPorts(22)
.withCreateContainerCmdModifier(cmd -> cmd.withHostConfig(
new HostConfig().withPortBindings(new PortBinding(Ports.Binding.bindPort(22), new ExposedPort(22)))
))
.withCommand("user:pass:::home");
@BeforeAll
static void start() throws IOException {
SFTP.start();
}
@AfterAll
static void stop() {
SFTP.stop();
}
}
The full working Spring Boot application can be downloaded here.
Upvotes: 3
Reputation: 5230
I don't know the purpose of the test in question, but as an alternative to mocking I could suggest testing against a fully functional SFTP server, just as originally intended.
The trick is to use Docker and some Docker-enablement java library like Testcontainers.
atmoz/sftp
the users can be configured using environment vars - see the documentation).Upvotes: 1
Reputation: 17657
In case you are using JUnit 5 Jupiter (might be easily adaptable to JUnit 4 as well) I´ve written an article on how to do it using the atmoz/sftp Docker image together with Testcontainers.
The full working example can be found here
https://overflowed.dev/blog/sftp-testing-junit-testcontainers-atmoz-sftp/
This is basically how you would define your TestContainer with SFTP
private static final GenericContainer sftp = new GenericContainer(
new ImageFromDockerfile()
.withDockerfileFromBuilder(builder ->
builder
.from("atmoz/sftp:latest")
.run("mkdir -p /home/" + USER + "/upload; chmod -R 007 /home/" + USER)
.build()))
//.withFileSystemBind(sftpHomeDirectory.getAbsolutePath(), "/home/" + USER + REMOTE_PATH, BindMode.READ_WRITE) //uncomment to mount host directory - not required / recommended
.withExposedPorts(PORT)
.withCommand(USER + ":" + PASSWORD + ":1001:::upload");
Upvotes: 3
Reputation: 13281
Regarding the unanswered/able question What's the best mock framework for Java?, a Mockito approach would be:
Get the needed libraries into your (test) class path. (https://mvnrepository.com/artifact/org.mockito)
Mock the SftpSession. (Via annotation private @Mock SftpSession sftpSession;
...plus the according initialization/enablement, or (manually) via sftpSession = Mockito.mock(SftpSession.class);
)
a. See, whether the SessionFactory is needed (for test) at all, if so also mock.
Mock/verify/reset any interactions (within your tests) with the mocked objects. (Like Mockito.when(sftpSession.foo(x,y,z)).then...
or Mockito.verify(sftpSession, Mockito.times(n)).foo(x,y,z);
)
Further reading:
Upvotes: 2