diff --git a/example/simple/client/main.go b/example/simple/client/main.go index ba8f265e..e9272946 100644 --- a/example/simple/client/main.go +++ b/example/simple/client/main.go @@ -33,4 +33,11 @@ func main() { log.Fatalf("error from grpc: %v", err) } log.Printf("Greeting: %s (return code %d)", r.Message, r.ReturnCode) + + name = "world" + r, err = c.SayHello(context.Background(), &pb.Request{Name: name}) + if err != nil { + log.Fatalf("error from grpc: %v", err) + } + log.Printf("Greeting: %s (return code %d)", r.Message, r.ReturnCode) } diff --git a/example/simple/stub/simple.json b/example/simple/stub/simple.json index 6bbf0913..2438a3c9 100644 --- a/example/simple/stub/simple.json +++ b/example/simple/stub/simple.json @@ -1,15 +1,32 @@ -{ - "service": "Gripmock", - "method": "SayHello", - "input": { - "equals": { - "name": "tokopedia" +[ + { + "service": "Gripmock", + "method": "SayHello", + "input": { + "equals": { + "name": "tokopedia" + } + }, + "output": { + "data": { + "message": "Hello Tokopedia", + "return_code": 1 + } } }, - "output": { - "data": { - "message": "Hello Tokopedia", - "return_code": 1 + { + "service": "Gripmock", + "method": "SayHello", + "input": { + "equals": { + "name": "world" + } + }, + "output": { + "data": { + "message": "Hello World", + "return_code": 1 + } } } -} +] \ No newline at end of file diff --git a/stub/storage.go b/stub/storage.go index 914216cf..4faf810d 100644 --- a/stub/storage.go +++ b/stub/storage.go @@ -27,6 +27,10 @@ type storage struct { } func storeStub(stub *Stub) error { + return stubStorage.storeStub(stub) +} + +func (sm *stubMapping) storeStub(stub *Stub) error { mx.Lock() defer mx.Unlock() @@ -34,10 +38,10 @@ func storeStub(stub *Stub) error { Input: stub.Input, Output: stub.Output, } - if stubStorage[stub.Service] == nil { - stubStorage[stub.Service] = make(map[string][]storage) + if (*sm)[stub.Service] == nil { + (*sm)[stub.Service] = make(map[string][]storage) } - stubStorage[stub.Service][stub.Method] = append(stubStorage[stub.Service][stub.Method], strg) + (*sm)[stub.Service][stub.Method] = append((*sm)[stub.Service][stub.Method], strg) return nil } @@ -269,6 +273,10 @@ func clearStorage() { } func readStubFromFile(path string) { + stubStorage.readStubFromFile(path) +} + +func (sm *stubMapping) readStubFromFile(path string) { files, err := ioutil.ReadDir(path) if err != nil { log.Printf("Can't read stub from %s. %v\n", path, err) @@ -287,13 +295,26 @@ func readStubFromFile(path string) { continue } + if byt[0] == '[' && byt[len(byt)-1] == ']' { + var stubs []*Stub + err = json.Unmarshal(byt, &stubs) + if err != nil { + log.Printf("Error when unmarshalling file %s. %v. skipping...", file.Name(), err) + continue + } + for _, s := range stubs { + sm.storeStub(s) + } + continue + } + stub := new(Stub) err = json.Unmarshal(byt, stub) if err != nil { - log.Printf("Error when reading file %s. %v. skipping...", file.Name(), err) + log.Printf("Error when unmarshalling file %s. %v. skipping...", file.Name(), err) continue } - storeStub(stub) + sm.storeStub(stub) } } diff --git a/stub/storage_test.go b/stub/storage_test.go new file mode 100644 index 00000000..55b157c4 --- /dev/null +++ b/stub/storage_test.go @@ -0,0 +1,137 @@ +package stub + +import ( + "encoding/json" + "io/ioutil" + "testing" + + "github.com/stretchr/testify/require" +) + +func Test_readStubFromFile(t *testing.T) { + tests := []struct { + name string + mock func(service, method string, data []storage) (path string) + service string + method string + data []storage + }{ + { + name: "single file, single stub", + mock: func(service, method string, data []storage) (path string) { + dir, err := ioutil.TempDir("", "") + require.NoError(t, err) + tempF, err := ioutil.TempFile(dir, "") + require.NoError(t, err) + defer tempF.Close() + + var stubs []Stub + for _, d := range data { + stubs = append(stubs, Stub{ + Service: service, + Method: method, + Input: d.Input, + Output: d.Output, + }) + } + byt, err := json.Marshal(stubs) + require.NoError(t, err) + _, err = tempF.Write(byt) + require.NoError(t, err) + + return dir + }, + service: "user", + method: "getname", + data: []storage{ + { + Input: Input{Equals: map[string]interface{}{"id": float64(1)}}, + Output: Output{Data: map[string]interface{}{"name": "user1"}}, + }, + }, + }, + { + name: "single file, multiple stub", + mock: func(service, method string, data []storage) (path string) { + dir, err := ioutil.TempDir("", "") + require.NoError(t, err) + tempF, err := ioutil.TempFile(dir, "") + require.NoError(t, err) + defer tempF.Close() + + var stubs []Stub + for _, d := range data { + stubs = append(stubs, Stub{ + Service: service, + Method: method, + Input: d.Input, + Output: d.Output, + }) + } + byt, err := json.Marshal(stubs) + require.NoError(t, err) + _, err = tempF.Write(byt) + require.NoError(t, err) + + return dir + }, + service: "user", + method: "getname", + data: []storage{ + { + Input: Input{Equals: map[string]interface{}{"id": float64(1)}}, + Output: Output{Data: map[string]interface{}{"name": "user1"}}, + }, + { + Input: Input{Equals: map[string]interface{}{"id": float64(2)}}, + Output: Output{Data: map[string]interface{}{"name": "user2"}}, + }, + }, + }, + { + name: "multiple file, single stub", + mock: func(service, method string, data []storage) (path string) { + dir, err := ioutil.TempDir("", "") + require.NoError(t, err) + + for _, d := range data { + tempF, err := ioutil.TempFile(dir, "") + require.NoError(t, err) + defer tempF.Close() + + stub := Stub{ + Service: service, + Method: method, + Input: d.Input, + Output: d.Output, + } + byt, err := json.Marshal(stub) + require.NoError(t, err) + _, err = tempF.Write(byt) + require.NoError(t, err) + } + + return dir + }, + service: "user", + method: "getname", + data: []storage{ + { + Input: Input{Equals: map[string]interface{}{"id": float64(1)}}, + Output: Output{Data: map[string]interface{}{"name": "user1"}}, + }, + { + Input: Input{Equals: map[string]interface{}{"id": float64(2)}}, + Output: Output{Data: map[string]interface{}{"name": "user2"}}, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + sm := stubMapping{} + sm.readStubFromFile(tt.mock(tt.service, tt.method, tt.data)) + require.ElementsMatch(t, tt.data, sm[tt.service][tt.method]) + }) + } +} diff --git a/stub/stub_test.go b/stub/stub_test.go index 894937b4..0f3b8e5c 100644 --- a/stub/stub_test.go +++ b/stub/stub_test.go @@ -284,15 +284,13 @@ func TestStub(t *testing.T) { "service":"Testing", "method":"TestMethod", "data":{ - "field1":"hello field1", - "field2":"hello field2", - "field3":"hello field4" + "field1":"hello field1" } }` return httptest.NewRequest("GET", "/find", bytes.NewReader([]byte(payload))) }, handler: handleFindStub, - expect: "Can't find stub \n\nService: Testing \n\nMethod: TestMethod \n\nInput\n\n{\n\tfield1: hello field1\n\tfield2: hello field2\n\tfield3: hello field4\n}\n\nClosest Match \n\ncontains:{\n\tfield1: hello field1\n\tfield3: hello field3\n}", + expect: "Can't find stub \n\nService: Testing \n\nMethod: TestMethod \n\nInput\n\n{\n\tfield1: hello field1\n}\n\nClosest Match \n\ncontains:{\n\tfield1: hello field1\n\tfield3: hello field3\n}", }, { name: "error find stub equals",