Предотвратить изменение значений указателя структуры во время тестирования - PullRequest
0 голосов
/ 09 мая 2020

Как сделать так, чтобы любое изменение, сделанное для значений структуры, оставалось только в подтесте, т.е. чтобы они не были затронуты вне подтеста. Я не могу вносить какие-либо изменения в структуры, так как они создаются автоматически с использованием кодогенератора swagger. Вот пример:

package main

import (
    "testing"
)

func TestTyre(t *testing.T) {
    type Tyre struct {
        Color *string
    }
    type Vehicle struct {
        Tyre Tyre
    }

    color := "black"
    tyreForTest := Tyre{Color: &color}
    expectedTyreColor := color

    t.Run("negativeTest", func(t *testing.T) {
        tyre := tyreForTest               // would have worked if there weren't any pointer variables
        *tyre.Color = "blue"              // here I expect value to change only for this subtest

        vehicle := Vehicle{Tyre: tyre}
        actualTyreColor := vehicle.Tyre.Color

        ok := (expectedTyreColor == *actualTyreColor)
        if ok {
            t.Error("Color should be blue")
        }
    })
    t.Run("positiveTest", func(t *testing.T) {
        tyre := tyreForTest

        vehicle := Vehicle{Tyre: tyre}
        actualTyreColor := vehicle.Tyre.Color

        ok := (expectedTyreColor == *actualTyreColor)
        if !ok {
            t.Error("Color should be black, instead of", *actualTyreColor)
        }
    })
}

Вывод:

=== RUN   TestTyre
=== RUN   TestTyre/negativeTest
=== RUN   TestTyre/positiveTest
    TestTyre/positiveTest: prog.go:39: Color should be black, instead of blue
--- FAIL: TestTyre (0.00s)
    --- PASS: TestTyre/negativeTest (0.00s)
    --- FAIL: TestTyre/positiveTest (0.00s)
FAIL

1 Ответ

0 голосов
/ 09 мая 2020

Вы предотвращаете это, не разделяя переменную color между тестовыми примерами - каждый из ваших тестовых примеров получает новый Tyre, но оба они указывают на одну и ту же память, хранящую значение цвета. Итак, когда вы меняете tyre.Color в отрицательном тестовом примере, вы обновляете значение переменной color, а другой тестовый пример tyre.Color также указывает на эту переменную.

Простое решение будет иметь функцию makeTyre(), которая получает совершенно новую шину с собственной памятью для хранения цвета и получения шины для каждого теста:

package main

import (
        "testing"
)

type Tyre struct {
        Color *string
}
type Vehicle struct {
        Tyre Tyre
}

func makeTyre() Tyre {
        color := "black"
        return Tyre{Color: &color}
}

func TestTyre(t *testing.T) {
        expectedTyreColor := "black"

        t.Run("negativeTest", func(t *testing.T) {
                tyre := makeTyre()
                *tyre.Color = "blue"
                vehicle := Vehicle{Tyre: tyre}
                actualTyreColor := vehicle.Tyre.Color

                ok := (expectedTyreColor == *actualTyreColor)
                if ok {
                        t.Error("Color should be blue")
                }
        })
        t.Run("positiveTest", func(t *testing.T) {
                tyre := makeTyre()

                vehicle := Vehicle{Tyre: tyre}
                actualTyreColor := vehicle.Tyre.Color

                ok := (expectedTyreColor == *actualTyreColor)
                if !ok {
                        t.Error("Color should be black, instead of", *actualTyreColor)
                }
        })
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...