Working with code R008

R008 - Failed to instantiate class under test

If you receive the output code R008, this means that Diffblue Cover was unable to construct an instance of SomeClass. This may be caused by a variety of reasons, most commonly the class does not have a package-visible constructor or factory method for SomeClass. This code can also be caused because the factory method takes arguments, throws, returns null or returns a subtype.

The rest of this page provides further detail on troubleshooting an R008 output code.

Note that the examples below (unless otherwise specified) are generated using Diffblue Cover on parsers from the Apache Tika project.

Find the root cause

Get a partial test

A good tool to investigate coverage issues is to get a partial test from Diffblue Cover. This is best done on the method or class that had the original R008 code to produce only the necessary partial tests for troubleshooting.

In Cover Plugin for IntelliJ, partial tests are available by default, all you have to do is click on the button to write tests.

Run/Debug the test

Running the partial test (e.g. with a debugger) can help you find the cause of the issue. Based on what the test contains, one of the following scenarios may apply:

Detailed Examples

Throwing constructor

The following example shows how to troubleshoot when a constructor that may throw an exception causes Diffblue Cover to output an R008 code.

The following is a partial test generated by Diffblue Cover (via IntelliJ) when the constructor for ChmDirectoryListingSet throws an exception.

    /**
     * Method under test: {@link ChmDirectoryListingSet#toString()}
     */
    @Test
    @Ignore("TODO: Complete this test")
    public void testToString() {
        // TODO: Complete this test.
        //   Reason: R008 Failed to instantiate class under test.
        //   Diffblue Cover was unable to construct an instance of ChmDirectoryListingSet.
        //   Add a package-visible constructor or a factory method for the class under test.
        //   If such a method is already present but Diffblue Cover does not find it, it can
        //   be specified using custom rules for inputs:
        //   https://docs.diffblue.com/knowledge-base/cli/custom-inputs/
        //   This can happen because the factory method takes arguments, throws, returns null
        //   or returns a subtype.
        //   See https://diff.blue/R008

        // Arrange
        // TODO: Populate arranged inputs
        ChmDirectoryListingSet chmDirectoryListingSet = null;

        // Act
        String actualToStringResult = chmDirectoryListingSet.toString();

        // Assert
        // TODO: Add assertions on result
    }

Observe that here the "Arrange" section is unable to create an instance of the ChmDirectoryListingSet class. The partial test leaves this for the developer to resolve (note the "TODO").

This can be resolved by ensuring the constructor(s) of ChmDirectoryListingSet do not throw exceptions, or by the addition of a new constructor that does not throw for use in testing.

Throwing static method

The following example shows how to troubleshoot when a static method, which may throw an exception, causes Diffblue Cover to output an R008 code.

The following is a partial test generated by Diffblue Cover (via IntelliJ) when the static method getAnnotationProperty of the CTAKESUtils class throws an exception.

    /**
     * Method under test: {@link CTAKESUtils#getAnnotationProperty(IdentifiedAnnotation, CTAKESAnnotationProperty)}
     */
    @Test
    @Ignore("TODO: Complete this test")
    public void testGetAnnotationProperty() {
        // TODO: Complete this test.
        //   Reason: R008 Failed to instantiate class under test.
        //   Diffblue Cover was unable to construct an instance of CTAKESUtils.
        //   Add a package-visible constructor or a factory method for the class under test.
        //   If such a method is already present but Diffblue Cover does not find it, it can
        //   be specified using custom rules for inputs:
        //   https://docs.diffblue.com/knowledge-base/cli/custom-inputs/
        //   This can happen because the factory method takes arguments, throws, returns null
        //   or returns a subtype.
        //   See https://diff.blue/R008

        // Arrange
        // TODO: Populate arranged inputs
        IdentifiedAnnotation annotation = null;
        CTAKESAnnotationProperty property = CTAKESAnnotationProperty.BEGIN;

        // Act
        String actualAnnotationProperty = CTAKESUtils.getAnnotationProperty(annotation, property);

        // Assert
        // TODO: Add assertions on result
    }

Observe that here the "Arrange" section is unable to find suitable inputs and the partial test leaves these missing inputs for the developer to resolve (note the "TODO").

Here the message with the R008 code indicates that the CTAKESUtils is unable to be instantiated and the "Act" section shows the call to the static method getAnnotationProperty. Fixing the test (here by providing a suitable value for the annotation variable) will create a working test.

Alternative solutions in this situation include:

  • Introduce a default constructor (even if only for testing) that can provide a suitable value for annotation.

  • Modify the static method to not throw exceptions.

Private constructor

The following example shows how to troubleshoot when Diffblue Cover cannot instantiate a class due to the constructor being private. This can cause Diffblue Cover to output an R008 code. Note that this example is generated from the Core Banking example project.

The following is a partial test generated by Diffblue Cover (via IntelliJ) when trying to create a test for the Account class.

    /**
     * Method under test: {@link Account.AccountStatement#getTransactions()}
     */
    @Test
    @Disabled("TODO: Complete this test")
    void testAccountStatementGetTransactions() {
        // TODO: Complete this test.
        //   Reason: R008 Failed to instantiate class under test.
        //   Diffblue Cover was unable to construct an instance of Account.AccountStatement.
        //   Add a package-visible constructor or a factory method for the class under test.
        //   If such a method is already present but Diffblue Cover does not find it, it can
        //   be specified using custom rules for inputs:
        //   https://docs.diffblue.com/knowledge-base/cli/custom-inputs/
        //   This can happen because the factory method takes arguments, throws, returns null
        //   or returns a subtype.
        //   See https://diff.blue/R008

        // Arrange
        // TODO: Populate arranged inputs
        Account.AccountStatement accountStatement = null;

        // Act
        List<Transaction> actualTransactions = accountStatement.getTransactions();

        // Assert
        // TODO: Add assertions on result
    }

Here the partial test indicates that Diffblue Cover is unable to construct an instance of the Account.AccountStatement class to use with getTransactions. Examination of the Account.AccountStatement code shows that the only constructor is private, as shown below.

  /** AccountStatement of an account, which holds the list of all executed transactions. */
  public class AccountStatement {
    private final List<Transaction> transactions;

    /** Constructor. */
    private AccountStatement() {
      transactions = new ArrayList<Transaction>();
    }

    // Other code omitted
  }

This can be resolved by providing a constructor for Account.AccountStatement that is not private.

Unable to find suitable arguments

The following example shows how to troubleshoot when Diffblue Cover does not find the right combination of constructor and inputs to test a method. This can cause Diffblue Cover to output an R008 code.

The following is a partial test generated by Diffblue Cover (via IntelliJ) when trying to create a test for the endDocument method of Word2006MLDocHandler.

    /**
     * Methods under test:
     *
     * <ul>
     *   <li>{@link Word2006MLDocHandler#endDocument()}
     *   <li>{@link Word2006MLDocHandler#endPrefixMapping(String)}
     *   <li>{@link Word2006MLDocHandler#startDocument()}
     *   <li>{@link Word2006MLDocHandler#startPrefixMapping(String, String)}
     * </ul>
     */
    @Test
    @Ignore("TODO: Complete this test")
    public void testEndDocument() throws SAXException {
        // TODO: Complete this test.
        //   Reason: R008 Failed to instantiate class under test.
        //   Diffblue Cover was unable to construct an instance of Word2006MLDocHandler.
        //   Add a package-visible constructor or a factory method for the class under test.
        //   If such a method is already present but Diffblue Cover does not find it, it can
        //   be specified using custom rules for inputs:
        //   https://docs.diffblue.com/knowledge-base/cli/custom-inputs/
        //   This can happen because the factory method takes arguments, throws, returns null
        //   or returns a subtype.
        //   See https://diff.blue/R008

        // Arrange
        // TODO: Populate arranged inputs
        Word2006MLDocHandler word2006MLDocHandler = null;

        // Act
        word2006MLDocHandler.endDocument();
        String prefix = "";
        word2006MLDocHandler.endPrefixMapping(prefix);
        word2006MLDocHandler.startDocument();
        String prefix1 = "";
        String uri = "";
        word2006MLDocHandler.startPrefixMapping(prefix1, uri);

        // Assert
        // TODO: Add assertions on result
    }

The key to understanding the trouble here is that Diffblue Cover is able to write tests for other methods (including the constructor) of the Word2006MLDocHandler class. For example, the following test is successfully created by Diffblue Cover.

    /**
     * Method under test: {@link Word2006MLDocHandler#startElement(String, String, String, org.xml.sax.Attributes)}
     */
    @Test
    public void testStartElement() throws SAXException {
        OfficeParserConfig officeParserConfig = new OfficeParserConfig();
        officeParserConfig.setIncludeDeletedContent(true);
        officeParserConfig.setIncludeMoveFromContent(true);
        officeParserConfig.setUseSAXDocxExtractor(true);
        officeParserConfig.setUseSAXPptxExtractor(true);
        ParseContext parseContext = mock(ParseContext.class);
        when(parseContext.get((Class<OfficeParserConfig>) any())).thenReturn(officeParserConfig);
        DefaultHandler handler = new DefaultHandler();
        XHTMLContentHandler xhtml = new XHTMLContentHandler(handler, new Metadata());

        Word2006MLDocHandler word2006MLDocHandler = new Word2006MLDocHandler(xhtml, new Metadata(), parseContext);
        WstxSAXParser wstxSAXParser = new WstxSAXParser();
        word2006MLDocHandler.startElement("Uri", "Local Name", "Q Name", wstxSAXParser);
        verify(parseContext).get((Class<OfficeParserConfig>) any());
        assertEquals(-1, wstxSAXParser.getColumnNumber());
        assertEquals(0, wstxSAXParser.getLength());
    }

In this example, the problem can be resolved by ensuring that the endDocument method does not always throw exceptions. However, if the inputs required for the endDocument method to not throw exceptions are complex to create, Diffblue Cover may still produce partial tests and an R008 code.

Constructor from third-party library

The following example shows how to troubleshoot when a class required for the test has a constructor/dependency from a third-party library causing Diffblue Cover to output an R008 code.

The following is a partial test generated by Diffblue Cover (via IntelliJ) when the constructor for the NameEntityExtractor class requires an argument that comes from a third-party library.

    /**
     * Method under test: {@link NameEntityExtractor#NameEntityExtractor(NameFinderME)}
     */
    @Test
    @Ignore("TODO: Complete this test")
    public void testConstructor() throws IOException {
        // TODO: Complete this test.
        //   Reason: R008 Failed to instantiate class under test.
        //   Diffblue Cover was unable to construct an instance of NameEntityExtractor.
        //   Add a package-visible constructor or a factory method for the class under test.
        //   If such a method is already present but Diffblue Cover does not find it, it can
        //   be specified using custom rules for inputs:
        //   https://docs.diffblue.com/knowledge-base/cli/custom-inputs/
        //   This can happen because the factory method takes arguments, throws, returns null
        //   or returns a subtype.
        //   See https://diff.blue/R008

        // Arrange
        // TODO: Populate arranged inputs
        NameFinderME nameFinder = null;

        // Act
        NameEntityExtractor actualNameEntityExtractor = new NameEntityExtractor(nameFinder);

        // Assert
        // TODO: Add assertions on result
    }

Observe that here the "Arrange" section is unable to construct a NameFinderME instance. Here the message with the R008 code indicates that the NameEntityExtractor is unable to be instantiated and can be deduced from the test name testConstructor.

This can be resolved in four ways.

  1. By using the --mock argument to Diffblue Cover, e.g. here --mock opennlp.tools.namefind.NameFinderME

  2. By fixing the partial test.

  3. By creating an alternative constructor for NameEntityExtractor that does not require the third-party library.

  4. By ensuring Diffblue Cover can construct an instance of NameFinderME in the current project.

Last updated