jmockit / jmockit1

Advanced Java library for integration testing, mocking, faking, and code coverage
Other
458 stars 238 forks source link

Throwable subclass is not mockable #719

Closed dlipofsky closed 2 years ago

dlipofsky commented 2 years ago

There are previous tickets claiming this is a feature, not a bug, and claiming that you should never need to mock a throwable. However there can be throwable subclasses without public constructors, in which case there is no way to test how your code handles exceptions. This includes most exceptions in the AWS SDK 2.x code (software.amazon.awssdk:s3:2.17.124).

Tested with JMockit 1.35 and 1.44. Previous tickets:

import mockit.Injectable;
import org.junit.Test;
import software.amazon.awssdk.awscore.exception.*;
import software.amazon.awssdk.core.exception.SdkException;
import software.amazon.awssdk.services.s3.S3Client;

public class S3UploadTest {

    @Test
    public void testS3Upload(
            @Injectable S3Client s3ClientMock,
            @Injectable AwsServiceException awsServiceException,
            @Injectable AwsErrorDetails awsErrorDetails,
            @Injectable SdkException sdkException) {
        ...
    }
}

returns

java.lang.IllegalArgumentException: class software.amazon.awssdk.awscore.exception.AwsServiceException is not mockable (mock parameter "awsServiceException")
rliesenfeld commented 2 years ago

The way to test the code that handles such exceptions is by setting up the condition which triggers the exception inside the third-party library. If you can't create such a test, then perhaps the associated exception handling is not needed.

dlipofsky commented 2 years ago

@rliesenfeld In most cases we are talking about mocking out something that is external - a call to a remote server, database, etc. The remote server of course doesn't exist for the unit tests, so the tests really don't use the third-party library, just an @Injectable of that type. This is one of the primary use cases for a mocking framework! So there is no possibility of triggering an exception inside the third-party library, since we never make it into the third-party code. Your answer is basically saying "don't write unit tests, only write integration tests" which is not just bad practice but not even possible in this case.

dlipofsky commented 2 years ago

@rliesenfeld , did I make a clear argument why this is a problem?