46

プライベート フィールドを持つ 1 つのパッケージに構造体があります。

package foo

type Foo struct {
    x int
    y *Foo
}

また、別のパッケージ (たとえば、ホワイト ボックス テスト パッケージ) がそれらにアクセスする必要があります。

package bar

import "../foo"

func change_foo(f *Foo) {
    f.y = nil
}

一種の「フレンド」パッケージであることを宣言する方法、またはから のプライベート メンバーbarにアクセスできるその他の方法はありますが、他のすべてのパッケージ (おそらく の何か) に対してはそれらをプライベートに保ちますか?foo.Foobarunsafe

4

5 に答える 5

1

あなたがテストしているのは、そのパッケージのオブジェクトの状態を変更するパッケージ機能だと思いますが、新しい状態が正しいことを確認するために変更された内部投稿を確認したいと考えています。

パッケージのスコープを超えてアクセスできるように、プライベートフィールドの作成Getと機能が役立つ場合があります。Set

package foo

type Foo struct {
    x int
    y *Foo
}

func (f *Foo) GetY() *Foo {
    return f.y
}

func (f *Foo) SetY(newY *Foo) {
    f.y = newY
}

これらのGetとの考え方はSet、フィールドへの読み取りおよび/または書き込みアクセスを制限することですが、それらを直接エクスポートすると、常に読み取り+書き込みアクセスが自動的に付与されます。微妙な違いですが、真の目標がプライベート フィールドのみを読み取り、それらを操作しないことである場合 (パッケージの内部が独自の方法で行う)、検討する価値があります。

最後に、パッケージ内のすべてのプライベート フィールドにこれらのタイプのラッパーを追加することに慣れていない場合は、そのパッケージ内の新しいファイルにそれらを記述し、ビルド タグを使用して通常のビルドでそれを無視し、それを含めることができます。テストビルドで(テストをトリガーする場所/方法に関係なく)。

// +build whitebox

// Get() and Set() function
go test --tags=whitebox

通常のビルドはテスト ファイルのビルドを無視するため、最終的なバイナリには含まれません。このパッケージがまったく異なるエコシステムの他の場所で使用されている場合、ビルド タグの制約により、このファイルはビルドされません。

于 2020-06-05T07:34:45.567 に答える