Working with code R013
R013 - No inputs found that don't throw a trivial exception
eLearning
Overview
If you receive the output code R013, this means that Diffblue Cover cannot write tests for a method because it is unable to find inputs to provide to the method that don't cause trivial exceptions, such as NullPointerException
. Please consider the parameters of the method under test, along with the class variables and instance variables it uses to ensure that it is easily possible to assign reasonable values for these quantities that do not cause trivial exceptions to be thrown.
A possible cause of an R013 is that the method under test uses a private member with an unset or bad value, as is shown in the example below:
There are three solutions to this scenario - ensure that value
is initialized with a proper value, make value
public, or provide a getter and a setter for value
.
Ensure that your method is testable. A good way to do this is to write a test yourself using the available constructor and setter methods.
If you have ensured that the method you want to analyze is testable, and are still getting an R013 code, you can further investigate the cause of the issue.
Find the root cause
A good tool to investigate coverage issues is to get a partial test from Diffblue Cover.
In Cover Plugin for IntelliJ, partial tests are available by default, all you have to do is click on the button to write tests.
In the CLI, pass in the --keep-partial-tests
option.
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 you see, one of the following scenarios may apply.
Missing input values
Consider the following example where we want tests for the setType()
method:
Diffblue Cover will not write a full test and will render an R013 instead. To find out what the issue is, let us get the partial tests as explained earlier. In our case we get one partial test:
The NullPointerException
on line 19 tells us that Diffblue Cover was unable to find a shiftedTypeId
that matches one of the keys in the map.
We provide them manually by using custom inputs. In our case, we can create a DiffblueRules.yml
file as below and place it at the root of the module:
("immediate" stands for constant primitive or String)
This will prompt Diffblue Cover to use 1112
as a value for parameters named shiftedTypeId
and thus give us a test that does not throw a NullPointerException
:
Unsettable fields
In this trivial example, there is no way to set name
to a non-null value:
This can be fixed by providing constructors or setters that assign that field:
Inputs that are hard to build: mock
If some inputs to the method under test are difficult to build, perhaps because they require complex configuration or need to read some external resources, it might be useful to mock those. Diffblue Cover automatically mocks some objects, but it might be useful to force-mock some specific classes in some cases.
Assuming that BlackBox
is difficult to build in the example below:
the CLI provides an option to force-mock a class: --mock=io.diffblue.example.BlackBox
which allows Diffblue Cover to produce full coverage without having to build BlackBox
:
Inputs that are hard to build: refactor
For better results, an alternative to mocking is to refactor the method under test so that the logic can be tested independently of the problematic input.
Take the following example of a method that extracts comments from a file:
Since Diffblue Cover cannot create file resources, no complete test can be produced, but by separating the logic between the file reading and the filtering as follows:
we can get unit tests for the method that does not rely on a file resource.
Note that it is also possible to access a property file as a resource using custom inputs.
Dependency on environment variables
This example will yield an R013 because getProperty()
will return null unless the system property is set:
In Cover CLI, this can be done using the -D
option (see Commands & Arguments) e.g. -DtheProperty=something
. In Cover Plugin, environment variables can be set in the run configuration.
Last updated