-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
154 lines (122 loc) · 4.13 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
package main
import (
"context"
"fmt"
"os"
"time"
"github.com/google/wire"
)
type Bar string
func main() {
// 依存関係を手動で注入
// message := model.NewMessage()
// greeter := model.NewGreeter(message)
// e := model.NewEvent(greeter)
// wireのInjectorによる依存性注入
e, err := InitializeEvent("test phrase")
if err != nil {
fmt.Printf("failed to create event: %s\n", err)
os.Exit(2)
}
e.Start()
baz, err := InitializeBaz(context.Background())
if err != nil {
fmt.Printf("failed to create Baz: %s\n", err)
os.Exit(2)
}
fmt.Println("----")
fmt.Println(baz.X)
bar := InitializeBar()
fmt.Println(bar)
foobar := InitializeFooBar()
fmt.Println(foobar.MyBar)
fmt.Println(foobar.MyFoo)
valueFoo := InitializeValueFoo()
fmt.Println(valueFoo)
fieldFoo1 := InitializeFieldFoo1()
fmt.Println(fieldFoo1)
fieldFoo2 := InitializeFieldFoo2()
fmt.Println(fieldFoo2)
// mock関連のコード
fmt.Printf("Real time greeting: %s [current time elided]\n", initApp().Greet()[0:15])
// Approach A モックを手動で作成し、そのモックをインジェクターに渡す。
// このアプローチは、事前にモックを準備する必要がある場合に有効です
fmt.Println("Mock Approach A")
mt := newMockTimer()
// モック用のアプリ生成。引数に依存関係パッケージのモックを渡す
mockedApp := initMockedAppFromArgs(mt)
fmt.Println(mockedApp.Greet())
mt.T = mt.T.AddDate(1999, 0, 0)
fmt.Println(mockedApp.Greet())
// Approach B インジェクターにモックを生成させ、依存関係をモックしたアプリの構造体を返す
fmt.Println("Approach B")
appWithMocks := initMockedApp()
fmt.Println(appWithMocks.app.Greet())
appWithMocks.mt.T = appWithMocks.mt.T.AddDate(1999, 0, 0)
fmt.Println(appWithMocks.app.Greet())
// interface DI用
// Dog owner と Cat ownerのテスト
dogOwner := initializeDogOwner()
fmt.Println(dogOwner.Animal.Bark())
catOwner := initializeCatOwner()
fmt.Println(catOwner.Animal.Bark())
}
// appSetは実際のアプリを作成するためのプロバイダーセットでsう
var appSet = wire.NewSet(
wire.Struct(new(app), "*"),
wire.Struct(new(greeter), "*"),
wire.InterfaceValue(new(timer), realTime{}), // timerインタフェースを実装している構造体はrealTimeを扱う
)
// appSetWithoutMocksはモック化された依存関係を利用しアプリを作成するプロバイダーセットです。
// モック化された依存関係は除外され、インジェクターへの引数として提供されなければなりません。
var appSetWithoutMocks = wire.NewSet(
wire.Struct(new(app), "*"),
wire.Struct(new(greeter), "*"),
)
// mockAppSetはモック化されたアプリと、モック化された依存関係も含んで生成するためのプロバイダーセットです。
// これはアプローチBに利用されます。
var mockAppSet = wire.NewSet(
wire.Struct(new(app), "*"),
wire.Struct(new(greeter), "*"),
wire.Struct(new(appWithMocks), "*"),
// モック化された各依存パッケージにおいて、プロバイダーを追加し、関連するインターフェースに具体的な型をバインドするためにwire.Bindを使ってください
newMockTimer,
wire.Bind(new(timer), new(*mockTimer)),
)
type timer interface {
Now() time.Time
}
// realTime implements timer with the real time
type realTime struct{}
func (realTime) Now() time.Time {
return time.Now()
}
// mockTimer implements timer using a mocked time.
type mockTimer struct {
T time.Time
}
// mockTimerのポインタを返すプロバイダ
func newMockTimer() *mockTimer {
return &mockTimer{}
}
func (m *mockTimer) Now() time.Time {
return m.T
}
// greeter issues greetings with the time provided by T.
type greeter struct {
T timer
}
func (g greeter) Greet() string {
return fmt.Sprintf("Good day! It is %v", g.T.Now())
}
type app struct {
g greeter
}
func (a app) Greet() string {
return a.g.Greet()
}
// appWithMocks はアプローチBのために使われます。これはアプリと、モックかされた依存関係を返します。
type appWithMocks struct {
app app
mt *mockTimer
}