Насмешливые функции, вызываемые из другого в golang

Я пытаюсь заглушить os.Stat и ioutil.ReadFile(path) в соответствии с приведенным ниже кодом или, если вам нравится, здесь, на игровой площадке [1]

package main

import (
    "fmt"
    "io/ioutil"
    "os"
    "strings"
)

func AssignFileValueFrom(path string, val *string) {
    var (
        tempValue []byte
        err       error
    )

    if _, err = os.Stat(path); err == nil {
        if err != nil {
            fmt.Println("There was a os stat error:", err)
        }

        tempValue, err = ioutil.ReadFile(path)
        if err != nil {
            fmt.Println("There was an io read error:", err)
        }
        *val = strings.TrimSpace(string(tempValue))
    }
}

Я использовал свидетельство и пробовал следовать примеру здесь [2]

package main

import (
    "testing"

    "github.com/stretchr/testify/mock"
)

type osMock struct {
    mock.Mock
}

func (o osMock) Stat(path string) (interface{}, error) {
    return nil, nil
}

func TestAssignFileValueFrom(t *testing.T) {
    var test string
    osm := new(osMock)
    osm.On(`Stat`, `./.test`).Return([]byte(`1`), nil)

    AssignFileValueFrom(`./.test`, &test)
    // assert.Equal(t, `1`, test)
    osm.AssertExpectations(t)
}

Что я не правильно делаю ??

[1] https://play.golang.org/p/xcbdMkMwoBN

[2] https://github.com/stretchr/testify#mock-package


person Ikenna    schedule 29.03.2018    source источник
comment
Вы ничего не издевались. Я предлагаю вам передать io.Reader в AssignFileValueFrom вместо пути. Вам не нужно писать тесты для std lib, в ней уже есть тесты.   -  person mpm    schedule 29.03.2018


Ответы (2)


Ваш код с osMock никак не влияет на выполнение функции AssignFileValueFrom. Существует прямой вызов os.Stat, и он не будет заменен только потому, что вы где-то объявили osMock.
Чтобы провести фактическое тестирование, вы должны использовать interfaces и внедрение зависимостей, чтобы иметь возможность протестировать свой код.
Прежде всего os.Stat вызов должен быть заменен вызовом вашей структуры, которая реализует интерфейс с таким же определенным методом. И вам нужно создать как минимум 2 реализации этого интерфейса: 1 - это фактический рабочий код для использования, 2 - макет вашей структуры osMock для использования в тесте. И вам нужно ввести его или передать AssignFileValueFrom, а затем использовать для вызова метода Stat для него.

person Pavlo Strokov    schedule 29.03.2018

Спасибо, ребята, за ваш вклад. Я переписал свои тесты следующим образом.

package main

import (
    "io/ioutil"
    "os"
    "testing"

    "github.com/stretchr/testify/assert"
)

var (
    err      error
    testFile *os.File
    test string
)

const (
    TestPrefix  = `test_file_prefix`
    FileContent = `1234`
)

func init() {
    testFile, err = ioutil.TempFile(os.TempDir(), TestPrefix)
    if err != nil {
        panic(err)
    }

    err = ioutil.WriteFile(testFile.Name(), []byte(FileContent), 0644)
    if err != nil {
        panic(err)
    }
}

func TestAssignFileValueFrom(t *testing.T) {
    AssignFileValueFrom(testFile.Name(), &test)

    assert.Equal(t, test, FileContent)
}
person Ikenna    schedule 01.04.2018