Question

I'm trying to write JUnit tests for my code but with in some of my methods other methods are called. Is it possible to mock these calls out?

E.g.

s3FileWrite(File file, Status status)
{
  S3 s3         = new S3(file.getName, s3Service)
  String key    = s3.getKey();
  String bucket = s3.getBucket();
  File tmp = new File("tmp/" + s3.getName());

  writeFile(key, bucket, tmp, status); //local method call I want to mock out
}//awsFileWrite

The writeFile method is what I want to mock out and it's part of the class I am testing, but I don't know how to mock it out. I thought mocking out the class I'm testing and then adding the call to my expectations would do it but it still calls the method.

Can anyone give me some advice on what to do here please?

EDIT:

My JMock code looks like this:

@Test
public void testS3FileWrite()
{       
    fileName     = context.mock(File.class);
    s3Service    = context.mock(FileDataAccessor.class);
    s3           = context.mock(S3.class);          
    reportWriter = context.mock(ReportWriter.class); 

    try
    {
        context.checking(new Expectations(){{           
            oneOf(fileMetaData).getKey();
            will(returnValue("s3Key")); 

            oneOf(fileMetaData).getBucketName();
            will(returnValue("BucketName"));

            oneOf(fileMetaData).getName();
            will(returnValue("TempFile"));  

            ((MethodClause) oneOf (any(File.class))).method("File").with(same("tmp/TempFile")); 

            oneOf(reportWriter).writeFile(with(same("s3Key")),
                                   with(same("BucketName")), 
                                   with(any(File.class), 
                                   with(same(Status.OK)));
        }});//Expectations
    }
    catch (Exception e)
    {
        ErrorStatus.debug("Exception in ReportTest.testS3FileWrite: " + e);
    }//try-catch  

    ReportWriter test = new ReportWriter(status);
    test.awsFileWrite(fileName, Status.OK);
}//testAWSFileWrite
Was it helpful?

Solution

PowerMock lets you partially mock classes, but it's designed for EasyMock not JMock. In any case, this is not the best approach.

Add a new class FileWriter and move the writeFile method to it, then in your class under test, delegate to one:

// default implementation, can be replaced in tests
FileWriter fileWriter = new FileWriter();

writeFile(key, bucket, tmp, status) {
    fileWriter.write(key, bucket, tmp, status);
}; 

In your test code, overwrite the fileWriter field in a the class under test (add a setter or make the field protected) with a mock FileWriter.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top