How to write mock for structs in Go

I want to write unit test for a function Hirethat will require ridicule CarFactoryand Carstructs. See the following code:

package main

type Car struct {
    Name string
}

func (h Car) Run() { ... }

type CarFactory struct {}

func (e CarFactory) MakeCar() Car {
    return Car{}
}

func Transport(cf CarFactory) {
    ...
    car := cf.MakeCar()
    car.Run()
    ...
}

In other OOP languages, such as Java, C # or C ++, I can simply define CarFactoryMockand CarMockthat extend CarFactoryand Carthen override the method MakeCar()to return the objectCarMock

class CarMock extends Car {
    public Run() {...}
}

class CarFactoryMock extends CarFactory {
    public Car MakeCar() { return new CarMock(); }                                                                                                                                                                                        
}

Transport(new CarFactoryMock())

How to achieve this in Go?

Please note that I can modify the prototype and source code function Transport, but must keep the tags CarFactoryand Carthe same as they are taken from the third package


The last piece of code was about the Man and the Employee, which leads to confusion`.

+8
source share
2

. Go , , .

,

type Car struct {
    Name string
}

func (c Car) Run() { 
    fmt.Println("Real car " + c.Name + " is running")
}

type CarFactory struct {}

func (cf CarFactory) MakeCar(name string) Car {
    return Car{name}
}

Go , Transport struct.

type ICar interface {
    Run()
}

type ICarFactory interface {
    MakeCar(name string) ICar
}

func Transport(cf ICarFactory) {
    ...
    car := cf.MakeCar("lamborghini")
    car.Run()
    ...
}

type CarMock struct {
    Name string
}

func (cm CarMock) Run() {
    fmt.Println("Mocking car " + cm.Name + " is running")
}

type CarFactoryMock struct {}
func (cf CarFactoryMock) MakeCar(name string) ICar {
    return CarMock{name}
}

Transport(CarFactoryMock{}). Transport (CarFactory {}), go

cannot use CarFactory literal (type CarFactory) as type ICarFactory in argument to Transport:
    CarFactory does not implement ICarFactory (wrong type for MakeCar method)
        have MakeCar(string) Car
        want MakeCar(string) ICar

, MakeCar ICar MakeCar Car. . , , Car ICar.

type CarFactoryWrapper struct {
    CarFactory
}

func (cf CarFactoryWrapper) MakeCar(name string) ICar {
    return cf.CarFactory.MakeCar(name)
}

Transport(CarFactoryWrapper{CarFactory{}})

https://play.golang.org/p/6YyeZP4tcC

+10

.

type Employee interface {
    GetHuman() Human
}

type RealEmployee struct {
    Company string
    h Human
}

func (e RealEmployee) GetHuman() Human {
    return e.h
}

// Call Hire with real employee
Hire(RealEmployee{h: RealHuman})

Hire Employee, MockEmployee .

func Hire(e Employee) {
    ...
    h := e.GetHuman()
    fmt.Println(h.Name)
    ...
}

// Mock Employee instance
type MockEmployee struct {
    Company string
    h Human
}

func (m MockEmployee) GetHuman() Human {
    return m.h
}

// Call Hire to test with mock employee
Hire(MockEmployee{h: MockHuman})
+2

Source: https://habr.com/ru/post/1663296/


All Articles