Насмешка в GO лэнг - PullRequest
       11

Насмешка в GO лэнг

0 голосов
/ 01 апреля 2020

Я новичок в Go, и я все еще пытаюсь разобраться в его концепции. Я пытаюсь создать простой модульный тест и хочу Mock один из его сервисов. Я хочу высмеять my_mod_2.EmpInfo в нем, чтобы не вызывать реальную службу.

method-1. go

package my_mod_1

import (
    "awesomeProject-1/my-mod-2"
)

func CreateAndSendMail() string {
    svc := my_mod_2.EmpInfo{}
    name := svc.GetName()
    empAddress := svc.GetAddress()
    return name + " lives in " + empAddress
}

Вот Emp. go

package my_mod_2

import "fmt"

type EmpInfo struct {}

func (o EmpInfo) GetName()  string{
    fmt.Println("Called actual")
    return "John Doe"
}

func (o EmpInfo) GetAddress() string {
    return "US"
}

Вот method-1_test. go

package my_mod_1

import (
    "testing"
)

func TestCreateAndSendMail(t *testing.T) {
    val := CreateAndSendMail()
    if val != "John Doe lives in US" {
        t.Error("Value not matched")
    }
}

Я вижу Called actual в выполнение теста. Я знаю, что должен создать макет, используя interface, но я просто не получаю его. Может кто-нибудь помочь мне с этим небольшим кодом?

Ответы [ 2 ]

3 голосов
/ 01 апреля 2020

Прежде всего, вам нужно подготовить свой код для использования интерфейсов и макетов. Для этого я предлагаю вам объявить интерфейс Service рядом с методом CreateAndSendMail. В этом случае лучше передать экземпляр службы методу или использовать его в качестве переменной экземпляра структуры, к которой относится ваш метод:

type Service interface {
    GetName() string
    GetAddress() string
}

func CreateAndSendMail(svc Service) string {
    name := svc.GetName()
    empAddress := svc.GetAddress()
    return name + " lives in " + empAddress
}

или

type Service interface {
    GetName() string
    GetAddress() string
}

type S struct {
    svc Service
}

func (s *S) CreateAndSendMail() string {
    name := s.svc.GetName()
    empAddress := s.svc.GetAddress()
    return name + " lives in " + empAddress
}

Тогда ваш EmpInfo будет неявно реализовывать ваш Service интерфейс. И это крутая особенность golang интерфейсов. После всех наших приготовлений мы готовы создать тест. Для этого мы можем реализовать макеты самостоятельно:

import (
    "testing"
)

type MockSvc struct {
}

func (s *MockSvc) GetName() string {
    return "Mocked name"
}

func (s *MockSvc) GetAddress() string {
    return "Mocked address"
}

func TestCreateAndSendMail(t *testing.T) {
    svc := &MockSvc{}

    val := CreateAndSendMail(svc)
    if val != "Mocked name lives in Mocked address" {
        t.Error("Value not matched")
    }
}

Также мы можем использовать специальный инструмент gomock для автоматизации процесса создания макета

0 голосов
/ 02 апреля 2020

Интерфейсы - это наиболее часто используемые Go функции, которые помогают при тестировании. Интерфейс в Go допускает Duck Typing, где вы можете переключить любой тип, в котором реализован интерфейс, который должен быть смоделирован другим типом.

В вашем примере у службы есть два следующих метода: GetName () и GetAddress (). Создайте интерфейс службы с помощью этих двух методов.

type Service Interface {
    GetName() string
    GetAddress() string
}

Теперь ваша структура EmpInfo уже реализует интерфейс службы. Создайте новую структуру MockService с теми же двумя функциями.

type MockService struct {}

func (ms *MockService) GetName() string {
// Mock Code
}

func (ms *MockService) GetAddress() string {
// Mock Code
}

Затем замените экземпляры EmpInfo на MockService там, где вам нужно.

PS: рассмотрите возможность добавления функций GetName и GetAddress с указателем на EmpInfo.

...