В продолжение предыдущей статьи напишем модульные тесты на 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.
Читайте также:
- Создание кастомного балансировщика нагрузки на Go для gRPC с приоритизацией адресов
- Изучаем gRPC и Flutter для разработки современных приложений
- Сравниваем REST, GraphQL и gRPC
Читайте нас в Telegram, VK и Дзен
Перевод статьи Izzan Alfadhil: Writing Unit Test In GO gRPC




