Реализовать интерфейс в структуре внутри функции - PullRequest
0 голосов
/ 10 апреля 2020

У меня есть фрагмент кода, который принимает реализацию io.Writer в качестве аргумента.

func printSummary(writer io.Writer) {
    // Implementation of the 'printSummary' method goes here.
}

Теперь я могу легко создать макет для создания модульного теста. Это будет выглядеть следующим образом:

type ioWriterMock struct {
    writtenBytes []byte
}

func (writer *ioWriterMock) Write(p []byte) (int, error) {
    writer.writtenBytes = append(writer.writtenBytes, p...)

    return 0, nil
}

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

I хотел бы создать мой тест, и что все, от чего зависит мой тест, находится внутри теста. Это по той простой причине, что все в одном месте, и мне не нужно сканировать разные файлы в моем пакете, чтобы найти разные детали, необходимые для моего теста.

В модульном тесте вы можете создать структуру и определить функции. Это делается с использованием следующего подхода:

func TestParse(t *testing.T) {
    type utCase struct {
        name                 string
        summary              string
        expectedWrittenBytes []byte
    }

    createUtCase := func(name, summary string, expWrittenBytes []byte) utCase {
        retVal := new(utCase)
        retVal.name = name
        retVal.summary = summary
        retVal.expectedWrittenBytes = expWrittenBytes

        return *retVal
    }
}

Таким образом, встраивание макета io.Writer в модульный тест можно выполнить следующим образом:

func TestParse(t *testing.T) {
    type ioWriterMock struct {
        writtenBytes []byte
    }
}

Одна вещь, которую я надеваю не могу понять, как я могу реализовать интерфейс io.Writer для этого типа.

1 Ответ

1 голос
/ 10 апреля 2020

Как рекомендует @mkopriva, поместите определение ioWriterMock рядом с функцией TestParse в файле _test.go. В go не разрешается помещать определение функции в другую функцию. Вы можете определить только тип структуры в функции.

Определяя тип ioWriterMock и метод Write внутри файла теста, он будет виден только во время выполнения теста. Он не будет присутствовать и, следовательно, будет виден при использовании пакета вне теста.

Также, учитывая приведенный пример, bytes.Buffer будет хорошей бесплатной заменой вашему ioWriterMock, как предлагает @Flimzy.

...