I have one method like below:
public final class someTask {
public void sampleMethod(String filePath) {
//It is calling Files.delete() method.
Files.delete(new File(filePath).toPath)
}
}
When I test above method(for example ValidRecord in that file, Valid file parameter or not etc) test cases, most of the time my test case failed. Please some one can help me how to test for above cases.
To get file I am using below snippet
#Mock
File fileMock;
#Rule
ExpectedException exception = ExpectedException.none();
PowerMockito.whenNew(File.class).withArguments(VALID_Path).thenReturn(fileMock);
PowerMockito.when(fileMock.exists()).thenReturn(true);
PowerMockito.when(fileMock.isFile()).thenReturn(true);
In this, I am not planning to test Files.deplete() method but I am planning test behaviour of my own method. In that process every time I am getting "java.nio.file.NoSuchFileException" exception even I create temporary file.
Please some can provide with example, how to test this.
One might argue that your approach is wrong by verifying the behaviour through mocking and interactions. I would do the following
Create a temp file on local file system
Call the method sampleMethod
Verify that the file doesn't exist anymore.
A valuable approach to such kinds of question is to go one step back criticize your application design. Ask yourself, whether you have design issues, especially when you feel that testing your code seems to be a bit difficult.
And indeed: You can/should improve the design of your software!
Let's start with your class (btw, I changed names to camel-casing):
public final class SomeTask {
public void sampleMethod(String filePath) {
Files.delete(new File(filePath).toPath);
}
}
I am going to ignore exceptions. Also, somewhere in your code you are using this class:
SomeTask task = new SomeTask();
String filePath = ...
task.sampleMethod(filePath);
The first thing to realize: In your class SomeTask you have a dependency to a delete-a-file functionality. Make this dependency visible!
But how do you do that? With an interface:
#FunctionalInterface
public interface FileDeletor {
void delete(String filePath);
}
You now can change your class by adding a field for such a deletor:
public final class SomeTask {
private final FileDeletor deletor;
public SomeTask(FileDeletor deletor) {
this.deletor = Objects.requireNonNull(deletor);
}
public void sampleMethod(String filePath) {
deletor.delete(filePath);
}
}
With this approach you delegate the technical doing of a file deletion to another class that now must implement the interface (shown below). This also makes your class more coherent because it now can concentrate on its own feature(s).
We now need a class that implements that interface:
public final class DefaultFileDeletor implements FileDeletor {
#Override
public void delete(String filePath) {
Files.delete(new File(filePath).toPath());
}
}
Note, that I am still ignoring exceptions here. Now we must also change the using side:
FileDeletor deletor = new DefaultFileDeletor();
SomeTask task = new SomeTask(deletor);
String filePath = ...
task.sampleMethod(filePath);
With this approach you can also build up an application via Spring autowiring or similar dependency injection frameworks.
Let us move on to the testing area. If you wish, you can also test your new class DefaultFileDeletor. But you know that it only uses a JDK functionality which itself is tested enough. No need to test this simple class.
But how can you now test your class SampleTask? First, you need an implementation of the interface just for the purposes of testing:
public class FileDeletorForTestPurposes implements FileDeletor {
private String filePath;
private boolean deleted;
#Override
public void delete(String filePath) {
this.filePath = filePath;
deleted = true;
}
public String getFilePath() {
return filePath;
}
public boolean isDeleted() {
return deleted;
}
}
Now you are able to test your code:
FileDeletorForTestPurposes deletor = new FileDeletorForTestPurposes();
SomeTask task = new SomeTask(deletor);
String filePath = ...
task.someMethod(filePath);
assertEquals(filePath, deletor.getFilePath());
assertEquals(true, deletor.isDeleted());
You are now also able to simply create a FileDeletor mock and use that by expressing expectations on it.
How to test delete files with Files.delete fuction below is the example
Lets say you have one function like below
public boolean deleteFilesWithinPath(Path path, int retryCount){
boolean status=false;
while (retryCount < 3) {
try {
Files.delete(path);
LOG.info("File deleted successfully from work Dir");
status=true;
break;
} catch (IOException e) {
try {
LOG.error(e.getMessage());
LOG.info("File was not deleted . Retrying ..");
status=false;
Thread.sleep(2000);
retryCount++;
} catch (InterruptedException e1) {
status=false;
LOG.error(e1.getMessage());
Thread.currentThread().interrupt();
}
}
}
return status;
}
Then you can test above function like below with Powermockit or Mockito
#Test
public void testdeleteFilesWithinPath() throws Exception{
File mockFileTemp = temporaryFolder.newFile("test.csv");
PowerMockito.mockStatic(Paths.class);
PowerMockito.mockStatic(Files.class);
int retrycount=0;
Path path = mockFileTemp.getAbsoluteFile().toPath();
boolean status = mftFileDownloadServiceImp.deleteFilesWithinPath(path,retrycount);
assertTrue(status);
}
#Test
public void testdeleteFilesWithinPathForIOException() throws Exception{
File mockFile = temporaryFolder.newFile("test.csv");
PowerMockito.mockStatic(Paths.class);
PowerMockito.mockStatic(Files.class);
Path path = mockFile.getAbsoluteFile().toPath();
Files.delete(path);
int retrycount=0;
try{
mftFileDownloadServiceImp.deleteFilesWithinPath(path,retrycount);
} catch (Exception e) {
assertThat(e).isInstanceOf(IOException.class);
}
}
Related
I have a function that I use to detect whether a certain directory path exists. Here's the function:
public boolean isRunningOnSandbox() {
return Files.isDirectory(Paths.get("/mySandbox/cloud/sandbox"));
}
As you can see, it relies on static method isDirectory. In my team, we do not use PowerMock for testing.
So, how can I test this method? I have tried writing a test like:
#Rule
public TemporaryFolder temporaryFolder;
#Test
public void test() throws IOException {
File parent = new File("/");
temporaryFolder = new TemporaryFolder(parent);
temporaryFolder.create();
File folder = temporaryFolder.newFolder("mySandbox", "cloud", "sandbox");
subject.isRunningOnSandbox();
}
But, I get an error
ava.io.IOException: Permission denied
because it doesn't let me create a temporary folder under the root. I am guessing there is a better way to test this code instead of trying to create a folder.
There are many ways to do it, onee of them migh be like the below one.
Assumming that isRunningOnSandbox method is in some class SomeClass, then refactor this class in this way:
public class SomeClass {
public boolean isRunningOnSandbox() {
return Files.isDirectory(Paths.get(getSanboxPath()));
}
protected String getSanboxPath(){
return "/mySandbox/cloud/sandbox";
}
}
and then in your tests inject into this class another directory to which you have access, for example:
public class SomeClassTest {
class SomeClassToTest extends SomeClass{
String folder;
public SomeClassToTest(String folder){
this.folder = folder;
}
#Override
protected String getSanboxPath(){
return folder;
}
}
static String sandboxFolder = "myTestSandobxFolder";
static Path tempDir;
#BeforeClass
public static void createFolder() throws IOException {
tempDir = Files.createTempDirectory(sandboxFolder);
}
#AfterClass
public static void deleteFolder() throws IOException {
Files.delete(tempDir);
}
#Test
public void IsRunningOnSandbox_shouldReturnTrueWhenPathExists() throws IOException {
//given
SomeClass testedObject = new SomeClassToTest(tempDir.toString());
//when
boolean result = testedObject.isRunningOnSandbox();
//then
assertThat(result).isTrue();
}
#Test
public void IsRunningOnSandbox_shouldReturnFalseWhenPathDoesNotExist() throws IOException {
//given
SomeClass testedObject = new SomeClassToTest("/abcdef123");
//when
boolean result = testedObject.isRunningOnSandbox();
//then
assertThat(result).isFalse();
}
}
The function you have shown is not suited for unit-testing: With unit-testing you try to find the bugs in small, isolated software pieces. But, which bugs could be in this example code that are not related to the other components, that is, the Files component, the Paths component and the actual file system?
The potential bugs in your example are about questions like "am I calling the right functions?" or "do I call the functions with proper values for the arguments?" or "do the functions I call return arguments as I expect" or "am I using the path that is also the path found in the file system". This can not be checked with unit-testing, but with integraton-testing.
Imagine you have the wrong path in mind. Then, in your unit-test you would also check against the same wrong path, and your unit-test would succeed. Only when running that test as an integration test on the real file system you could figure out that the path which you had in mind was wrong and did not match the actual path in the file system.
I have a method in my utilities:
public void createDirectories(final Path root, final Scaffolding scaffolding) throws FileAlreadyExistsException {
if (Files.exists(root)) {
throw new FileAlreadyExistsException("Root directory " + root.toString() + " already exists.");
} else {
Files.createDirectories(root);
// Create directories from the scaffolding object
}
}
I want to mock Files so I can test to make sure Files.createDirectories with the expected fields are called or not.
Can I do this with Mockito? Or do I need to actually create the directories and check for their existence in some tmp folder?
When you write something with tdd and have troubles consider it as signal of bad design. You don't need to mock static fields or find some tricky lib for do it. Instead of doing this make entity that represent filesystem and place all methods related to file operations to this class. With this refactor your code will be like that:
class UtilClass { //util classes are bad don't do it
private final FileSystem fileSystem;
public UtilClass(FileSystem fileSystem) {
this.fileSystem = fileSystem;
}
public void createDirectories(final Path root, final Scaffolding scaffolding) throws FileAlreadyExistsException {
if (fileSystem.exists(root)) {
throw new FileAlreadyExistsException("Root directory " + root.toString() + " already exists.");
} else {
fileSystem.createDirectories(root);
// Create directories from the scaffolding object
}
interface FileSystem {
boolean exists(Path path);
void createDirectories(Path path);
}
and test class
class UtilClassTest {
#Test(expected = FileAlreadyExistsException.class)
public void shouldThrowExceptionWhenRootPathExists() {
FileSystem mockFileSystem = Mockito.mock(FileSystem.class);
Mockito.when(mockFileSystem.exists(anyPath())).return(true);
UtilClass util = new UtilClass(mockFileSystem);
util.createDirectories(mock(Path.class), mock(Scaffolding.class))
}
}
In your code outside tests replace mock to implementation.
class FileSystemImpl implements FileSystem {
boolean exists(Path path){
return Files.exists(path);
}
createDirectories(Path path){
return Files.createDirectories(path);
}
}
and you don't need to touch file system in tests or mock static fields.
I'm sending you an example, which allows you to use the FileSystems Mock in a transparent way
#Test
#ExtendWith(MockfsExtension.class)
void testExecute_MockFSNew(FileSystem fileSystem) throws Exception {
Path master = Files.createDirectories(Paths.get("/fakedir/conf/java/rest/master"));
Path homologacao = Files.createDirectories(fileSystem.getPath("/fakedir/conf/java/rest/homologacao"));
Path dev = Files.createDirectories(fileSystem.getPath("/fakedir/conf/java/rest/dev"));
}
Paths.get return a mock fs, this is done using Mockito.mockStatic
It's also injecting FileSystem in paramter
using
package br.com.pulse.starter.builder.steps.impl;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.ParameterContext;
import org.junit.jupiter.api.extension.ParameterResolutionException;
import org.junit.jupiter.api.extension.ParameterResolver;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import com.github.marschall.memoryfilesystem.MemoryFileSystemBuilder;
public class MockfsExtension implements BeforeEachCallback, AfterEachCallback , ParameterResolver {
MockedStatic<FileSystems> mock;
private FileSystem fileSystem;
public FileSystem getFileSystem() {
return this.fileSystem;
}
#Override
public void beforeEach( ExtensionContext context ) throws Exception {
this.fileSystem = MemoryFileSystemBuilder.newEmpty().build();
mock = Mockito.mockStatic(FileSystems.class);
mock.when(() -> FileSystems.getDefault()).then(invocation -> {
System.out.println("Requested FakeFs >>>");
return fileSystem;
});
}
#Override
public void afterEach( ExtensionContext context ) throws Exception {
if (this.fileSystem != null) {
this.fileSystem.close();
}
mock.close();
}
#Override
public boolean supportsParameter( ParameterContext parameterContext , ExtensionContext extensionContext ) throws ParameterResolutionException {
return true;
}
#Override
public Object resolveParameter( ParameterContext parameterContext , ExtensionContext extensionContext ) throws ParameterResolutionException {
return this.fileSystem;
}
}
See:
https://github.com/marschall/memoryfilesystem
https://github.com/marschall/memoryfilesystem/issues/130
You cannot mock static methods with base Mockito, nor, in most cases, should you be, especially one provided by Java. You can mock static methods with PowerMock, but this is a Global core library.
The piece of code you are testing here is whether or not you get an exception if the directory exists. If Files.exists() is returning bad results, your program is toast either way. So what you should ultimately be testing is that the flow is being properly followed while depending on a fully implemented Files global.
#Test
public void testCreateDirectories() {
File tempFile = new File("test");
tempFile.delete(); //delete test directory if it exists
tempFile.deleteOnExit(); //and again when the test finishes
Path testPath = tempFile.getPath();
foo.createDirectories(testPath, mock(Scaffolding.class)); //should create path
Assert.assertTrue(tempFile.exists());
try {
foo.createDirectories(testPath, mock(Scaffolding.class)); //should FAE
Assert.fail(Should have thrown an FAE exception at this point!);
}
catch(FileAlreadyExistsException faee) {
logger.debug("Expected FAE exception thrown", faee);
}
}
This execution will go through both the true and false path and clean up after itself.
This double execution of the logic tests both paths and is designed to cover the following scenarios if your if statement manages to get mucked up.
boolean works as intended: both calls work, PASS
boolean is accidentally inverted: 1st call throws FAE, FAIL
boolean always returns false: 2nd call doesn't throw FAE, FAIL.
boolean always returns true: 1st call throws FAE, FAIL.
I am trying to figure out, how to re-run failed tests with usage of Espresso. I think it's a bit more complicated from common JUnit test case as you need to restore status in your app from before test start.
My approach is to create my own ActivityTestRule so I just copied whole code from this class and named it MyActivityTestRule.
In case of instrumentation tests rule will also need information of how we want to start our activity. I prefer to launch it myself rather than have environment to do it for me. So for example:
#Rule
public MyActivityTestRule<ActivityToStartWith> activityRule = new MyActivityTestRule<>(
ActivityToStartWith.class, true, false
);
So I also launch my activity in #Before annotation method:
#Before
public void setUp() throws Exception {
activityRule.launchActivity(new Intent());
}
And make clean up in #After annotation method:
#After
public void tearDown() throws Exception {
cleanUpDataBaseAfterTest();
returnToStartingActivity(activityRule);
}
Those methods - setUp(), tearDown() are essential to be called before/after each test run - to ensure the app state during the test start is correct.
Inside MyActivityTestRule I did few modifications so far. First thing is change of apply method from:
#Override
public Statement apply(final Statement base, Description description) {
return new ActivityStatement(super.apply(base, description));
}
It's a but unknown thing for me, as ActivityStatement placed in ActivityTestRule has super.apply method so it also wraps test statement in UiThreadStatement:
public class UiThreadStatement extends Statement {
private final Statement mBase;
private final boolean mRunOnUiThread;
public UiThreadStatement(Statement base, boolean runOnUiThread) {
mBase = base;
mRunOnUiThread = runOnUiThread;
}
#Override
public void evaluate() throws Throwable {
if (mRunOnUiThread) {
final AtomicReference<Throwable> exceptionRef = new AtomicReference<>();
getInstrumentation().runOnMainSync(new Runnable() {
public void run() {
try {
mBase.evaluate();
} catch (Throwable throwable) {
exceptionRef.set(throwable);
}
}
});
Throwable throwable = exceptionRef.get();
if (throwable != null) {
throw throwable;
}
} else {
mBase.evaluate();
}
}
}
No mather what I do with my tests I can never create case mRunOnUiThread boolean to be true. It will be true if within my test cases, tests with annotation #UiThreadTest will be present - or that's what I understood from code. It never happens though, I don't use anything like that so I decided to ignore this UiThreadStatement and change MyActivityTestRule to:
#Override
public Statement apply(final Statement base, Description description) {
return new ActivityStatement(base);
}
And my test cases run without any problem. Thanks to that all I have left - that wraps around mBase.evaluate() is:
private class ActivityStatement extends Statement {
private final Statement mBase;
public ActivityStatement(Statement base) {
mBase = base;
}
#Override
public void evaluate() throws Throwable {
try {
if (mLaunchActivity) {
mActivity = launchActivity(getActivityIntent());
}
mBase.evaluate();
} finally {
finishActivity();
afterActivityFinished();
}
}
}
In general launchActivity will be called only if I set in the 3rd parameter of ActivityTestRule constructor value true. But I launch tests by myself in setUp() so it never happens.
From what I understood mBase.evaluate() runs my code inside #Test annotation method. It also stops the test case during throwable being thrown. That means I can catch it and restart it - like proposed there:
How to Re-run failed JUnit tests immediately?
And okay I did something like that:
public class ActivityRetryStatement extends Statement {
private final Statement mBase;
private final int MAX_RUNS = 2;
public ActivityRetryStatement(Statement base) {
mBase = base;
}
#Override
public void evaluate() throws Throwable {
Throwable throwable = null;
for (int i = 0; i < MAX_RUNS; i++) {
try {
mBase.evaluate();
// if you reach this lane that means evaluate passed
// and you don't need to do the next run
break;
} catch (Throwable t) {
// save first throwable if occurred
if (throwable == null) {
throwable = t;
}
// my try that didn't work
launchActivity(testInitialIntent);
// I've returned test to starting screen but
// mBase.envaluate() didn't make it run again
// it would be cool now to:
// - invoke #After
// - finish current activity
// - invoke #Before again and start activity
// - mBase.evaluate() should restart #Test on activity started again by #Before
}
}
finishActivity();
afterActivityFinished();
// if 1st try fail but 2nd passes inform me still that there was error
if (throwable != null) {
throw throwable;
}
}
}
So those comments in catch block are parts I don't know how to do. I tried to perform launchActivity on intent I used in setUp() to run the test for the 1st time. But mBase.evaluate() didn't make it react (test case didn't go again) - nothing happened + it wouldn't really save me there I think. I lacked some initiations I do in #SetUp, it wasn't called again. I would really like to find a way how to properly restart whole test lifecycle #Before #Test #After over again. Maybe some call on Instrumentation or TestRunner from code.
Any thoughts about how it could be done?
You can use https://github.com/AdevintaSpain/Barista library for rerunning failed tests.
You can see more details about dealing with flaky tests here: https://github.com/AdevintaSpain/Barista#dealing-with-flaky-tests
The answer is super simple. Just make sure you upgrade your espresso tests to Junit 4, and then see this answer
edit: I apologize if the post has been considered too confusing, i'll edit it and leave only the parts regarding my problem...
I have written a class named "ArithmeticNode" which implements an interface containing the following methods:
public void turnOn() {
arithmeticServer.start();
}
public void turnOff(){
arithmeticServer.stop();
}
and contains also a private method:
private void negotiatePort(NodeManifest nodeManifest, ThriftServer arithmeticServer) {
while(true) {
int proposedPort = arithmeticServer.start();
int returnedPort = managementClient.registerNode(nodeManifest, proposedPort);
if(proposedPOrt != returnedPort) {
arithnemticServer.stop();
}
else
break;
}
}
What I'm trying to do is to write a test in which I create a number of these arithmetic nodes and make them register to a management node that I've already written and use as server. Then there will be a second part of my project where I'll make those nodes interact, but that's not part of the actual problem.
I have already written a working junit test:
#Test
public void testArithmeticServer() throws Exception {
List<NodeManifest> nodeManifests = new ArrayList<>();
nodeManifests.add(new NodeManifest("localhost", Arrays.asList(new String[]{"addition"})));
nodeManifests.add(new NodeManifest("localhost", Arrays.asList(new String[]{"subtraction","multiplication"})));
nodeManifests.add(new NodeManifest("localhost", Arrays.asList(new String[]{"addition","multiplication","division"})));
nodeManifests.add(new NodeManifest("localhost", Arrays.asList(new String[]{"addition","division"})));
List<ThriftServer> arithmeticServers = new ArrayList<>();
for (NodeManifest nodeManifest : nodeManifests) {
ThriftServer arithmeticServer = new ThriftServer(ArithmeticServiceHandler.class);
arithmeticServers.add(arithmeticServer);
negotiatePort(nodeManifest,arithmeticServer);
}
private void negotiatePort() {
while(true) {
int proposedPort = arithmeticServer.start();
int returnedPort = managementClient.registerNode(nodeManifest, proposedPort);
if(proposedPOrt != returnedPort) {
arithnemticServer.stop();
}
else
break;
}
}
I need to write a test where i don't have to put the negotiatePort method directly inside the test code, but I call for each node the private negotiatePort method I have inside my arithmeticNode class; I'm not sure if it's possible to do that and how. I hope I've been less confusing than the previous version of the post :-)
You can make the negotiatePort method package local. Then you would be able to call it within your test (which should reside in the same package). And nobody outside the package would be able to use it
I am very new to Mockito and jUnit and TDD in general and I try to learn the right way to do TDD. I need couples of example to kick start my brain. SO please help me
So I have a method getNameInc(String dirPath, String filenName). So given a fileName like bankAccount.pdf, and if in this folder, no file name bankAccount.pdf, then return bankAccountAA.pdf. If there is exist one bankAccount.pdf then return bankAccountBB.pdf The increment is AA-ZZ. When it reach ZZ then it roll back to AA. I already implement the logic of this method. How do I unit test this method using Mockiti and jUnit?
EDIT
Here is the class and methods that are involved.
public class PProcessor{
private final Map<Integer, String> incMap = new HashMap<Integer, String>();
private String getNameInc(String dirPath, String filenName){
String[] nameList = new File(dirPath).list(new FilenameFilter(){
public boolean accept(File file, String name) {
//only load pdf files
return (name.toLowerCase().endsWith(".pdf"));
}
});
//Return the number of occurance that a given file name appear
//inside the output folder.
int freq = 0;
for(int i=0; i<nameList.length; i++){
if(fileName.equals(nameList[i].substring(0, 8))){
freq++;
}
}
return incMap.get(freq);
}
private void generateIncHashMap(){
incMap.put(new Integer(0), "AA");
incMap.put(new Integer(1), "BB");
incMap.put(new Integer(2), "CC");
...
}
}
generateIncHashMap() will be called in the constructor to pre-generate the hash map
You are trying to test your getNameInc(..) method, I assume. When you call it, it looks for the files in the directory you specify, and based on what it finds, decorates the name you gave it.
To make the class unit-testable, you should abstract the dependency on the file system, so that in a mock, you can simulate whatever directory contents you want. Your class will accept an instance of this interface as a dependency, and call it to find out what's in the directory. When you use the class in your program for real, you will supply an implementation of this interface that delegates to the JDK filesystem calls. When you unit-test the class, you will supply Mockito mocks of this interface.
Avoid putting too much logic into the FilesystemImpl class, since you can't write a strict unit test for it. Keep it a very simple wrapper around the filesystem, so that all the intelligent stuff is in Yourclass, which you will write plenty of unit tests for.
public interface Filesystem {
boolean contains(String dirpath, String filename);
}
public class FilesystemImpl {
boolean contains(String dirpath, String filename) {
// Make JDK calls to determine if the specified directory has the file.
return ...
}
}
public class Yourmainclass {
public static void main(String[] args) {
Filesystem f = new FilesystemImpl();
Yourclass worker = new Yourclass(f);
// do something with your worker
// etc...
}
}
public class Yourclass {
private Filesystem filesystem;
public Yourclass(Filesystem filesystem) {
this.filesystem = filesystem;
}
String getNameInc(String dirpath, String filename) {
...
if (filesystem.contains(dirpath, filename) {
...
}
}
}
public class YourclassTest {
#Test
public void testShouldAppendAAWhenFileExists() {
Filesystem filesystem = Mockito.mock(Filesystem.class);
when(filesystem.contains("/some/mock/path", "bankAccount.pdf").thenReturn(true);
Yourclass worker = new Yourclass(filesystem);
String actual = worker.getNameInc("/some/mock/path", "bankAccount.pdf");
assertEquals("bankAccountAA.pdf", actual);
}
#Test
public void testShouldNotAppendWhenFileDoesNotExist {
Filesystem filesystem = Mockito.mock(Filesystem.class);
when(filesystem.contains("/some/mock/path", "bankAccount.pdf").thenReturn(false);
Yourclass worker = new Yourclass(filesystem);
String actual = worker.getNameInc("/some/mock/path", "bankAccount.pdf");
assertequals("bankAccount.pdf", actual);
}
}
Since there's a lot of duplication between the tests, you'd probably create a setup method and do some of the work there, and create some instance variables for the tests to use:
private static final String TEST_PATH = "/some/mock/path";
private static final String TEST_FILENAME = "bankAccount.pdf";
private Filesystem filesystem;
private Yourclass worker;
#Before
public void setUp() {
filesystem = Mockito.mock(Filesystem.class);
worker = new Yourclass(filesystem);
}
#Test
public void testShouldAppendAAWhenFileExists() {
when(filesystem.contains(TEST_PATH, TEST_FILENAME).thenReturn(true);
String actual = worker.getNameInc(TEST_PATH, TEST_FILENAME);
assertEquals("bankAccountAA.pdf", actual);
}
etc...
For what you have described there I wouldn't bother with Mockito, there doesn't seem to be anything to mock (because it is easy to manipulate the file system).
I would test ...
- What happens if I call getNameInc and there are no matching files already
- What happens if I call getNameInc and there are files AA-YY there already
- What happens if I call getNameInc and file ZZ is there already
The point of TDD though is that you should have already written these tests and then implemented your code to make the tests pass. So you won't really be doing TDD since you already have the code.