Record the problems encountered this week

I In the background unit test, the test results of run and debug mode are different

The flow chart of testing the update method under the controller at present

At present, the problem lies in parameter capture. In the debug mode, when I execute with one line, I will execute to the second line entityargumentcaptor When getvalue(), the test reports an error that no data has been captured.

1 Mockito.verify(this.Service).update(longArgumentCaptor.capture(),
2 Assertions.assertEquals(oldEntity.getName(), entityArgumentCaptor.getValue().getName());

Read the newspaper wrong

It says that parameters are not captured, possibly for two reasons.
1. Argument. May not be used in verify() captrue().
2. Capture() may be used in a pile, but it is not called. It is recommended to use capture() only in verify().

Finally, an example is given:

However, a comparison with the above code shows that the usage is completely consistent with the recommended one.

Then I tried to test directly with run mode, and the result passed.

Finally, I tested for a long time and reported an error because I didn't write the two parameters in verify() on the same line, as shown in lines 204 and 205

When I didn't write the parameters in the same line, in the debug mode, click next, jump to line 204, then jump to line 205, and then jump back to line 204 for some reason. The 204 line only captures the parameter of id.

After testing, neither of the two catchers captured the parameters.

The guess may be that debug executes statements line by line. When the parameters are not written on the same line, the execution may make an error and the statement will fail directly.

After putting the parameters on the same line, the execution result in debug mode is correct.

II The jpa parameter is not allowed to be null

Scenario: when the query parameter name is empty, all data will be displayed. The foreground transmits the query condition name to the background, and the name is null

An error was found during the test

jpa defined query

Page<PropertyCompany> findAllByNameContainingAndDeletedIsFalse(String name, Pageable pageable);

Reason: the findByXXX parameter of jpa cannot be null.

terms of settlement:
1: The service layer adds judgment. If it is null, it is set to an empty string.

public Page<PropertyCompany> page(String name, @NotNull Pageable pageable) {
    if (name == null) {
      name = "";

2. User defined query:

default Page<PropertyCompany> findAll(String name, @NotNull Pageable pageable) {
        Specification<PropertyCompany> specification = PropertyCompanySpecs.containingName(name);
        return this.findAll(specification, pageable);

public class PropertyCompanySpecs {
    public static Specification<PropertyCompany> containingName(String name) {
        if (name != null && !name.trim().isEmpty()) {
            return (root, criteriaQuery, criteriaBuilder) ->"name").as(String.class), String.format("%%%s%%", name.trim()));
        } else {
            return Specification.where(null);

What if you really want to query the field with null name?

You can use: findByNameIsNull is equivalent to sql statement where name is null

Three value transfer problem

The background is that the parent component in angular calls the child component and lets the child component operate on the incoming array.

Parent component: defined villages: Village [];
And passed to the sub components in the v layer

<component [setVillages]="villages"></component>`

Subcomponents: to avoid using villages During push and other operations, an error is reported because the incoming villages are undefined. The following operations are performed:

if (village === undefined) {
  villages = new Array<Village>();

Result: the child component's final operation on the villages does not affect the parent component's villages, and the villages in the parent component are still undefined.

Solution: the initial variable of villages defined in the parent component should be defined as follows:
villages = new Array<Village>();

At present, it is considered that: similar to c language, if the parameter of the function does not pass in the parameter address, it means that the operation is only a copy of data. If the address of the incoming parameter represents the actual incoming data, the variable outside the function will also change.
Here, if the array is in the sub component new Array(), it means that the memory is opened in the sub component, and the operation on the data does not affect the data of the parent component If the array opens up space in the parent component, it means that the child component operates on the data of the parent component.

Keywords: Spring Boot

Added by cougarreddy on Mon, 21 Feb 2022 12:24:13 +0200