-1

I want to write unittest case for CreateData() function, by mocking FetchAllData() and SaveData() which are in someother package(package2), please help me to mock the function with example,

Thanks in advance


func CreateData(input package1.InputRequest) (output package1.OututResponse){

    ..some code
    ..some code

    DBdata, err := package2.FetchAllData() //function to fetch data from database

    ..some code
    ..some code

    id, insertErr := package2.SaveData(someData) //function to insert data

    ..some code
    ..some code
}

I need to just mock the above function without modifying the function. I'm looking for that

sp007
  • 1
  • 2
  • 2
    It probably is much cleaner if you stop trying to mock these functions but provided them (or a suitable abstraction, e.g. in the form of an interface) to your function under test. Then you can inject a fake or a stub. Dead simple, very clean, easy to test and no mockery. – Volker Aug 29 '19 at 11:24
  • @Volker thanks for answer, Im new to the golang, can you please elaborate the answer with some code template so that will more convenient to the me to understand. – sp007 Aug 30 '19 at 05:32

1 Answers1

2

Make use of the interface feature. It may require some change to the dependencies (in this example, the package2).

Change your code to something like this (the point is, to define several interfaces for better testability):

type Fetcher interface {
    FetchAllData() ([]Data, error)
}

type Saver interface {
    SaveData([]Data) (int, error)
}


func CreateData(input package1.InputRequest) (output package1.OututResponse){

    ..some code
    ..some code

    // when you are writing tests, replace it with `s := NewMocking()`
    s := package2.NewStorage()

    DBdata, err := s.FetchAllData() //function to fetch data from database

    ..some code
    ..some code

    id, insertErr := s.SaveData(someData) //function to insert data

    ..some code
    ..some code
}

A little change to the package2 is needed:

type MyStorage struct {}

func (s *MyStorage) FetchAllData ([]Data, error) {
    // ... some fetching code
}

func (s *MyStorage) SaveData(someData []Data) (int, error) {
    // ... some saving code
}

func NewStorage() *MyStorage {
    // ... some initialization
}

When you want to do some tests without a requirement of package2, define your own mocking type:

type Mocking struct {}

func (s *Mocking) FetchAllData ([]Data, error) {
    // ... some mocking logic
}

func (s *Mocking) SaveData(someData []Data) (int, error) {
    // ... some mocking logic
}

func NewMocking() *Mocking {
    // ... initialize ...
}
ConnectionLost
  • 742
  • 4
  • 14
  • thanks for the answer, I understood this and what is the function NewMocking() does? is that return struct type to call mocked or fake FetchAllData()? if yes where should I define NewMocking() function. I'm new to golang so please give detailed clarification. – sp007 Aug 30 '19 at 05:28
  • and at `if !testing {...}` , what is `testing` ? – sp007 Aug 30 '19 at 06:41
  • @user10082110 yes you need a NewMocking function. And `if !testing {...}` is just to tell you that you can construct a mocked object when you need that. – ConnectionLost Aug 31 '19 at 05:53