В продолжение предыдущей статьи напишем модульные тесты на Go при помощи пакета testing.

Для написания и запуска модульных тестов в Go имеется встроенный пакет тестирования testing с соответствующими инструментами и соглашениями. Модульный тест на Go  —  это просто функция с конкретной сигнатурой и соглашением по именованию. Функция начинается с Test, ею принимается один параметр типа *testing.T. Соглашение по именованию для модульного теста Go всегда заканчивается на <example>_test.go.

Настройка тестового сервера

Начнем с написания метода для запуска сервера gRPC, этим методом возвращаются методы сервера gRPC и сетевой прослушиватель.

func setupTestServer() (*grpc.Server, net.Listener) {

db, err := dbconnection.StartDB()
db.DB()

if err != nil {
log.Fatal("failed to connect database", err)
} else {
log.Println("Connected to database")
}

lis, err := net.Listen("tcp", ":0") // Для доступного случайного порта используется порт «:0»
if err != nil {
log.Fatalf("Failed to listen: %v", err)
}

grpcServer := grpc.NewServer()

// Регистрируется сервис
bukuService := services.NewBukuService()
handler.NewGrpcBukuService(grpcServer, bukuService)

go grpcServer.Serve(lis)
return grpcServer, lis
}

Тестовый метод

Сначала объявляется ожидаемый результат этого теста, который затем сравнивается с фактическим результатом.

  • Ввод
{
"judul": "Test",
"penulis": "Test",
"kuantitas": 1,
"tempat_penyimpanan": "Test"
}
  • Ожидаемый результат
{
"id": 0,
"judul": "Test",
"penulis": "Test",
"kuantitas": 1,
"tempat_penyimpanan": "Test"
}

Просто проверим наличие ответа. Если один из элементов пуст, тест считается невыполненным.

func TestAddBuku(test *testing.T) {

grpcServer, lis := setupTestServer()
defer grpcServer.Stop()

conn, err := grpc.NewClient(lis.Addr().String(), grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
test.Fatalf("Failed to connect to server: %v", err)
}
defer conn.Close()

client := buku.NewBukuServiceClient(conn)

req := &buku.AddBukuRequest{
Judul: "Test",
Penulis: "Test",
Kuantitas: 1,
TempatPenyimpanan: "Test",
}

resp, err := client.AddBuku(context.Background(), req)

if err != nil {
test.Fatalf("Cant Create Respond : %v", err)
}

if resp.Judul == "" {
test.Error("Judul is empty")
}
if resp.Penulis == "" {
test.Error("Penulis is empty")
}
if resp.Kuantitas == 0 {
test.Error("Kuantitas is 0")
}
if resp.TempatPenyimpanan == "" {
test.Error("Tempat Penyimpanan is empty")
}
}

// Добавляется остальная часть модульного теста, если таковая имеется..

Весь код

package main

import (
"context"
"grpc-app/app/dbconnection"
"grpc-app/app/controller"
"grpc-app/app/services"
"grpc-app/app/generated/buku"
"log"
"net"
"testing"

"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
)

func setupTestServer() (*grpc.Server, net.Listener) {

db, err := dbconnection.StartDB()
db.DB()

if err != nil {
log.Fatal("failed to connect database", err)
} else {
log.Println("Connected to database")
}

lis, err := net.Listen("tcp", ":0") // Для доступного случайного порта используется порт «:0»
if err != nil {
log.Fatalf("Failed to listen: %v", err)
}

grpcServer := grpc.NewServer()

// Регистрируется сервис
bukuService := services.NewBukuService()
handler.NewGrpcBukuService(grpcServer, bukuService)

go grpcServer.Serve(lis)
return grpcServer, lis
}

func TestAddBuku(test *testing.T) {

grpcServer, lis := setupTestServer()
defer grpcServer.Stop()

conn, err := grpc.NewClient(lis.Addr().String(), grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
test.Fatalf("Failed to connect to server: %v", err)
}
defer conn.Close()

client := buku.NewBukuServiceClient(conn)

req := &buku.AddBukuRequest{
Judul: "Test",
Penulis: "Test",
Kuantitas: 1,
TempatPenyimpanan: "Test",
}

resp, err := client.AddBuku(context.Background(), req)

if err != nil {
test.Fatalf("Cant Create Respond : %v", err)
}

if resp.Judul == "" {
test.Error("Judul is empty")
}
if resp.Penulis == "" {
test.Error("Penulis is empty")
}
if resp.Kuantitas == 0 {
test.Error("Kuantitas is 0")
}
if resp.TempatPenyimpanan == "" {
test.Error("Tempat Penyimpanan is empty")
}
}

Запуск модульного теста

Командой go test модульный тест запускаем и смотрим за его прохождением.

Консольный вывод

Заключение

Со встроенным пакетом testing написать модульный тест на Go очень просто. Пишется метод вслед за конкретным соглашением по именованию и сигнатурой, он начинается с Test и принимает один параметр *testing.T. Затем файлу модульного теста присваивается название, которое заканчивается на _test.go, запускается тест командой go test.

Читайте также:

Читайте нас в Telegram, VK и Дзен


Перевод статьи Izzan Alfadhil: Writing Unit Test In GO gRPC

Предыдущая статьяApache Spark  —  типичные ошибки и их устранение
Следующая статьяC++: руководство по vector.erase