mirror of
https://github.com/github/codeql.git
synced 2026-04-25 00:35:20 +02:00
Java: Fix QLDoc style compliance and qhelp for mocking query
This commit is contained in:
@@ -1,14 +1,10 @@
|
||||
# J-T-001: Mocking all non-private methods of a class may indicate the unit test is testing too much
|
||||
|
||||
Mocking too many non-private methods of a class may indicate that the test is too complicated, possibly because it is trying to test multiple things at once.
|
||||
|
||||
## Overview
|
||||
|
||||
Mocking methods of a class is necessary for a unit test to run without overhead caused by expensive I/O operations necessary to compute their values. However, if a unit test ends up mocking all of them, it is likely a signal that the scope of the unit test is reaching beyond a single unit of functionality.
|
||||
Mocking methods of a class is necessary for unit tests to run without overhead caused by expensive I/O operations. However, when a unit test ends up mocking all non-private methods of a class, it may indicate that the test is too complicated, possibly because it is trying to test multiple things at once. Such extensive mocking is likely a signal that the scope of the unit test is reaching beyond a single unit of functionality.
|
||||
|
||||
## Recommendation
|
||||
|
||||
It is best to contain the scope of a single unit test to a single unit of functionality. For example, a unit test may aim to test a series of data-transforming functions that depends on an ORM class. Even though the functions may be semantically related with one another, it is better to create a unit test for each function.
|
||||
It is best to contain the scope of a single unit test to a single unit of functionality. For example, a unit test may aim to test a series of data-transforming functions that depend on an ORM class. Even though the functions may be semantically related with one another, it is better to create a unit test for each function.
|
||||
|
||||
## Example
|
||||
|
||||
@@ -30,14 +26,14 @@ public class TestORM {
|
||||
public void nonCompliant() {
|
||||
Employee sampleEmployee = new Employee("John Doe");
|
||||
EmployeeRecord employeeRecordMock = mock(EmployeeRecord.class); // NON_COMPLIANT: Mocked class has all of its public methods used in the test
|
||||
when(employeeRecordMock.add(Employee.class)).thenReturn(0); // Mocked EmployeeRecord.add
|
||||
when(employeeRecordMock.get(String.class)).thenReturn(sampleEmployee); // Mocked EmployeeRecord.get
|
||||
when(employeeRecordMock.update(Employee.class, String.class)).thenReturn(0); // Mocked EmployeeRecord.update
|
||||
when(employeeRecordMock.delete(Employee.class)).thenReturn(0); // Mocked EmployeeRecord.delete
|
||||
when(employeeRecordMock.add(sampleEmployee)).thenReturn(0); // Mocked EmployeeRecord.add
|
||||
when(employeeRecordMock.get("John Doe")).thenReturn(sampleEmployee); // Mocked EmployeeRecord.get
|
||||
when(employeeRecordMock.update(sampleEmployee, "Jane Doe")).thenReturn(0); // Mocked EmployeeRecord.update
|
||||
when(employeeRecordMock.delete(sampleEmployee)).thenReturn(0); // Mocked EmployeeRecord.delete
|
||||
}
|
||||
|
||||
@Test
|
||||
public void compliant1() {
|
||||
public void compliant() {
|
||||
Employee sampleEmployee = new Employee("John Doe");
|
||||
EmployeeRecord employeeRecordMock = mock(EmployeeRecord.class); // COMPLIANT: Only some of the public methods belonging to the mocked object are used
|
||||
when(employeeRecordMock.add(sampleEmployee)).thenReturn(0); // Mocked EmployeeRecord.add
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @id java/mocking-all-non-private-methods-means-unit-test-is-too-big
|
||||
* @name J-T-001: Mocking all non-private methods of a class may indicate the unit test is testing too much
|
||||
* @name Mocking all non-private methods of a class may indicate the unit test is testing too much
|
||||
* @description Mocking all non-private methods provided by a class might indicate the unit test
|
||||
* aims to test too many things.
|
||||
* @kind problem
|
||||
@@ -12,12 +12,15 @@
|
||||
|
||||
import java
|
||||
|
||||
/**
|
||||
* A call to Mockito's `mock` method.
|
||||
*/
|
||||
class MockitoMockCall extends MethodCall {
|
||||
MockitoMockCall() { this.getMethod().hasQualifiedName("org.mockito", "Mockito", "mock") }
|
||||
|
||||
/**
|
||||
* Gets the type that this call intends to mock. e.g.
|
||||
* ``` java
|
||||
* Gets the type that this call intends to mock. For example:
|
||||
* ```java
|
||||
* EmployeeRecord employeeRecordMock = mock(EmployeeRecord.class);
|
||||
* ```
|
||||
* This predicate gets the class `EmployeeRecord` in the above example.
|
||||
@@ -26,8 +29,8 @@ class MockitoMockCall extends MethodCall {
|
||||
}
|
||||
|
||||
/**
|
||||
* A method call that mocks a target method in a JUnit test. e.g.
|
||||
* ``` java
|
||||
* A method call that mocks a target method in a JUnit test. For example:
|
||||
* ```java
|
||||
* EmployeeRecord employeeRecordMock = mock(EmployeeRecord.class);
|
||||
* when(employeeRecordMock.add(sampleEmployee)).thenReturn(0); // Mocked EmployeeRecord.add
|
||||
* doReturn(0).when(employeeRecordMock).add(sampleEmployee); // Mocked EmployeeRecord.add
|
||||
|
||||
Reference in New Issue
Block a user