Recommend several open source class libraries, super easy to use, stay away from 996!

Today I will share with you a few Java open source class libraries, which are very easy to use for personal testing!

With them, you can say goodbye to a lot of repetitive work.

1. MapStruct

What does MapStruct do?

MapStruct is a code generator that can directly generate converters corresponding to Java objects based on annotations.

For example, to directly convert a Java object of type A to a Java object of type B, you only need to configure the mapping relationship between fields between them.

Why use it in the project?

Now any project is multi-layer, especially Web projects, often need to do object model conversion between multi-layer, such as DTO into BO.

DTO (Data Transfer Object): The data transfer object, the object that the Service transfers to the outside.
BO (Business Object): A business object, an object that encapsulates business logic output by the Service layer.

But this kind of conversion work is like when we were young, the teacher punished us to copy famous famous quotes 100 times. It is very boring and error-prone.

like this:

public class CarMapper {
    CarDto carDoToCarDto(Car car) {
        CarDto carDto = new CarDto();
        carDto.setCarId(car.getCarId());
        carDto.setWheel(car.getWheel());
        carDto.setCarType(car.getCarType());
        carDto.setCarColor(car.getCarColor());
        ......
    }

}

If Car has dozens of fields, and like Car, there are dozens of classes, you can imagine how cumbersome it is.

Before MapStruct, we used Apache or Spring's BeanUtils tool to do this automatically.

But there are two problems with such tools:

1. Poor performance

The poor performance is mainly caused by Apache's BeanUtils. It checks whether the field is readable and writable every time, and also generates the corresponding PropertyDescriptor according to the field.

These seriously affect its performance, so it is not recommended to use it in the Ali Java manual.

Spring's BeanUtils, although a lot of Apache BeanUtils read and write checks and corresponding attribute information records are simplified, but it is still called through reflection, and it is a large number of reflection calls. This performance is also unsatisfactory.

2. Do the conversion during runtime, and errors represent losses

Tools like BeanUtils have a unified name called the Java Object Mapping Framework.

Most of their implementations execute code at runtime and then copy the corresponding values ​​between Java objects.

The biggest problem with doing this during runtime is that errors cannot be found until the entire project is up and running. For example, when converting, the type is inconsistent and an error is reported.

For this kind of situation, we all know that this thing is like the opening ceremony has not been done well, and it has become an opening enemy...

If you can write the code and find the problem when compiling, this loss can be avoided.

The introduction of MapStruct is to solve the above two problems.

MapStruct is first and foremost a code generator. It generates a special tool class for conversion based on annotations. This tool class, like our own Java class, can be used directly, thus avoiding reflection.

At the same time, the conversion class it generates is also very simple, that is, by default, the value of the property with the same name is copied between two types of Java objects.

If there is a configuration, properties with different names can also be copied. So it performs well.

The sample code is as follows:

@Mapper
public interface CarMapper {

    CarMapper INSTANCE = Mappers.getMapper( CarMapper.class );

    @Mapping(target = "seatCount", source = "numberOfSeats")
    CarDto carDoToCarDto(Car car);
}

Because MapStruct is a code generator, it brings a huge benefit, that is, this guy will generate the corresponding class during the compilation phase. Therefore, if there is a similar type conversion problem, it will compile and report an error directly. Wait until it runs to find out. In this case, there will be no loss, which is really a very nice thing.

Code base address

https://github.com/mapstruct/mapstruct

2. Retrofit

What is Retrofit for?

Retrofit is a set of Http clients that can be used to access third-party Http services.

For example, if we want to call a URL of the Http protocol in our code, we can use it to access the URL and get the response result.

Why use it in the project?

In the company, some of our projects have the following characteristics:

  1. Not a Spring based project
  2. Need to frequently access a large number of third-party Http services
  3. The model for accessing Http services is usually asynchronous callbacks

In the past, when we accessed Http services, we used HttpClient directly.

However, HttpClient is really troublesome enough to use. There are also two main problems:

1. The splicing of request parameters and URLs is cumbersome

Request parameters and URL concatenation are just so annoying. Think about it, every time you call an interface, you need to splicing parameters yourself, some URLs, and even a dozen or 20 parameters need to be spliced.

Splicing is simple, boring, repetitive, and has no technical content, but the workload is not small, and time is really wasted.

URIBuilder uriBuilder = new URIBuilder(uriBase);
uriBuilder.setParameter("a", "valuea");
uriBuilder.setParameter("b", "valueb");
uriBuilder.setParameter("c", "valuec");
uriBuilder.setParameter("d", "valued");
uriBuilder.setParameter("e", "valuee");
uriBuilder.setParameter("f", "valuef");
uriBuilder.setParameter("g", "valueg");
uriBuilder.setParameter("h", "valueh");
uriBuilder.setParameter("i", "valuei");
...

2. Asynchronous callback needs to be done by yourself

The asynchronous callback model is not easy to deal with. The main reason is that you need to develop the thread pool yourself, manage the thread pool, and consider fault tolerance issues such as error retry, which is really troublesome.

Therefore, we need a set of libraries that can be used easily and can access third-party Http services by doing thread management without having to splicing parameters all the time.

In fact, we also thought about using the Feign framework. However, this set of things is too tightly bound to Spring. If you leave Spring, some of its functions cannot be used directly through annotations, and you must write your own code to call them.

Moreover, Feign still needs to develop it by itself in order to realize the use of asynchronous callbacks, especially in terms of coroutines.

At this point, Retrofit jumped into our selection.

In Retrofit's model, the asynchronous callback model is well supported, and we only need to implement a Callable.

And the coolest thing is that it has nothing to do with Spring.

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("http://xxx.example.com/")
        .build();

public interface BlogService {
    @GET("blog/{id}")
    Call<ResponseBody> getBlog(@Path("id") int id);
}

BlogService service = retrofit.create(BlogService.class);

Call<ResponseBody> call = service.getBlog(2);
// 用法和OkHttp的call如出一辙,
// 回调
call.enqueue(new Callback<ResponseBody>() {
    @Override
    public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
        try {
            System.out.println(response.body().string());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onFailure(Call<ResponseBody> call, Throwable t) {
        t.printStackTrace();
    }
});

You see, just by writing this code, we don't need to worry about the annoying Url splicing and asynchronous callback management. All handed over to Retrofit, really recommend.

Code base address

https://github.com/square/retrofit

3. Faker

What does Faker do?

Faker is a library of auxiliary tools specially used to generate various fake data.

For example, you want to generate a user with the same name and address as the real data.

Why use it in the project?

We often need to create data to test, but if there is no tool to assist, we create data by ourselves, there are some problems.

1. The data needs to be formatted

A lot of projects require some format that mimics real-world data as closely as possible.

For example, most of the names of domestic users are two-character or three-character names. They are called Wang Da, but they cannot be called Wang Da.

For another example, if the domestic address is No. xx, xx street, xx district, xx city, you can't write a few meaningless Chinese characters as the address.

Using data that is close to the real format, we can firstly detect whether there is a problem with our data parsing for users, and secondly, we can determine whether there is no problem with the length of the fields in the database.

Therefore, the format is important to produce reliable test results.

2. The amount of data is large

Some test data volumes are in the hundreds of thousands or millions, and these magnitudes of data are not generated only once.

Even almost every project, every test of every project, may require new data, which requires the continuous generation of energy sources.

What's more, sometimes we want to generate data of a certain relationship at the right time according to our requirements, or generate it at a certain frequency. For example, data is generated after two seconds; for example, a batch of data with the surname Wang is generated.

Combining the above three requirements, if we create our own data, it is really fatal.

Instead of developing it yourself, it is better to use the ready-made - Faker library was found by us.

The Faker library can create more than 300 kinds of data, and it is easy to expand and transform it to generate more data that meets our needs.

Faker faker = new Faker();

String name = faker.name().fullName(); // Miss Samanta Schmidt
String firstName = faker.name().firstName(); // Emory
String lastName = faker.name().lastName(); // Barton

String streetAddress = faker.address().streetAddress(); // 60018 Sawayn Brooks Suite 449

A few lines of code and we have a user we need.

After using Faker, the friends said that "there is more time to fish".

Code base address

https://github.com/DiUS/java-faker

4. Wiremock

What does Wiremock do?

Wiremock is a testing framework that can mock services.

For example, if you want to test the code logic of accessing Ali's payment-related interfaces, you can use it for testing.

Why use it in the project?

For example, we need to call the bank interface for fund business, and the WeChat interface for WeChat login... There is a problem with these tests of calling third-party services:

That is, relying too much on the other's platform. If the other platform restricts some IPs, or restricts the frequency of access, or if the service is maintained, it will affect our own functional testing.

In order to solve the above problems, before, we needed to write our own code to imitate the interface of the third party. After all our tests were done, we could debug with the third party. For this simulated interface, we call it a baffle.

However, this method is hard work, and no one wants to do it. Because every third party is connected, a baffle may be required. The hard work of making a baffle is purely for testing. If the third-party interface has been modified, you have to change it accordingly.

Everyone can think about it, if you were yourself, would you be willing to do such a thing?

At this time, the value of Wiremock is reflected. With Wiremock, there is no such thing as a baffle anymore. You can simulate the test directly in the unit test, like this:

WireMock.stubFor(get(urlPathMatching("/aliyun/.*"))
                .willReturn(aResponse()
                        .withStatus(200)
                        .withHeader("Content-Type", APPLICATION_JSON)
                        .withBody("\"testing-library\": \"WireMock\"")));

CloseableHttpClient httpClient = HttpClients.createDefault();
HttpGet request = new HttpGet(String.format("http://localhost:%s/aliyun/wiremock", port));
HttpResponse httpResponse = httpClient.execute(request);
String stringResponse = convertHttpResponseToString(httpResponse);

verify(getRequestedFor(urlEqualTo(ALIYUN_WIREMOCK_PATH)));
assertEquals(200, httpResponse.getStatusLine().getStatusCode());
assertEquals(APPLICATION_JSON, httpResponse.getFirstHeader("Content-Type").getValue());
assertEquals("\"testing-library\": \"WireMock\"", stringResponse);

Code base address

https://github.com/wiremock/wiremock

Epilogue

Although Java has many critics, one of the most important advantages of Java is its ecology, which has a dazzling variety of tool libraries.

I hope everyone is "lazy", don't bury your head in ineffective hard work, don't build your own wheels, you have to believe:

The problem you have encountered has basically been encountered by many people, and it has been solved by the great people, and the wheels have been built for you.


Hello, I'm Shimonai.

The technical director of a listed company, managing a technical team of more than 100 people.

I went from a non-computer graduate to a programmer, working hard and growing all the way.

I will write my own growth story into articles, boring technical articles into stories.

Welcome to pay attention to my official account. After following, you can receive learning materials such as high concurrency, algorithm brushing notes, and computer high score book list.

{{o.name}}
{{m.name}}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324069934&siteId=291194637