单元测试失败:嘲笑S3FileRead NullPointerException

时间:2020-04-26 05:41:01

标签: java unit-testing junit mockito

我的单元测试有问题,并由于此错误而失败。

Error: java.lang.NullPointerException
com.amazon.heimdalltttingestionservicelambda.s3.S3FileTransmissionTest.mockS3FileRead(S3FileTransmissionTest.java:66)
com.amazon.heimdalltttingestionservicelambda.s3.S3FileTransmissionTest.testSuccess(S3FileTransmissionTest.java:39)
at org.mockito.junit.MockitoJUnitRunner.run(Unknown Source)
public class S3FileTransmission {

    AmazonS3Encryption s3EncryptionReceiveClient;

    public void downloadDecryptWithS3Encryption(@NonNull final String fileKey, @NonNull final String bucketName,
                                                @NonNull final File file)
    {
        try {
            final InputStream downloadFileStream = this.s3EncryptionReceiveClient.getObject(bucketName,
                    fileKey).getObjectContent();

            FileUtils.copyInputStreamToFile(downloadFileStream, file);
            Environment.log("downloadDecryptWithS3Encryption:Completed file write to filepath: {} ", file.getPath());

        }  catch (final Exception e) {
            Environment.log("[%s]: Error in downloading and decrypting filekey:[%s]",
                    LogMetricKeys.S3_FILE_DECRYPTION_FAILURE_, fileKey);

        }
    }
}

单元测试代码:

@RunWith(MockitoJUnitRunner.class)
public class S3FileTransmissionTest extends BaseTester {

    AmazonS3Encryption s3EncryptionReceiveClient;
    @Mock
    S3FileTransmission s3FileTransmission;

    @Before
    public void setup() {
        super.setup();
        s3EncryptionReceiveClient = Mockito.mock(AmazonS3Encryption.class);
    }

    @Test
    public void testSuccess(){
        File file = new File("/test/text.csv");
        mockS3FileRead(prepareFileContent());
        s3FileTransmission.downloadDecryptWithS3Encryption(BUCKET, KEY, file);
    }

    private String prepareFileContent() {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(EmployeeLenelBadgeDataField.EXPECTED_HEADERS_STRING);
        stringBuilder.append("\n");

        for (int employeeIndex = 1; employeeIndex < 5; employeeIndex++) {
            stringBuilder.append(MockDataRecords.getEmployeeLenelBadgeDataRecord());
            stringBuilder.append("\n");
        }
        return stringBuilder.toString();
    }

    private void mockS3FileRead(String fileContent) {
        // Inject test data
        Answer<ObjectMetadata> answer = invocationOnMock -> {
            File file = invocationOnMock.getArgument(1);
            FileWriter fileWriter = new FileWriter(file);
            fileWriter.write(fileContent);
            fileWriter.flush();
            fileWriter.close();

            return null;
        };
        Mockito.when(s3EncryptionReceiveClient.getObject(anyString(), anyString()).getObjectContent()).thenAnswer(answer);
    }
}

1 个答案:

答案 0 :(得分:0)

嘲笑s3EncryptionReceiveClient.getObject()的方式是错误的。 正确的方法是:

@Before
public void setup() {
    super.setup();
    s3EncryptionReceiveClient = Mockito.mock(AmazonS3Encryption.class);
    SomeClassThatGetObjectReturns obj = Mockito.mock(SomeClassThatGetObjectReturns.class);
}

private void mockS3FileRead(String fileContent) {
    ...
    ...
    Mockito.when(s3EncryptionReceiveClient.getObject(anyString(), anyString()).thenReturn(obj)
    Mockito.when(obj.getObjectContent()).thenReturn(anInputStreamMockedObject);
}

这个想法是使用实​​际返回类型的正确模拟/虚拟模拟每个外部方法。