tha*_*hpk 12 unit-testing mocking go
我想为Hire函数编写单元测试,这需要模拟CarFactory和Car结构.请参阅以下代码:
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()
...
}
Run Code Online (Sandbox Code Playgroud)
在其它OOP语言如Java,C#或C++,我可以只定义CarFactoryMock和CarMock延伸CarFactory并Car然后覆盖MakeCar()方法返回一个CarMock对象
class CarMock extends Car {
public Run() {...}
}
class CarFactoryMock extends CarFactory {
public Car MakeCar() { return new CarMock(); }
}
Transport(new CarFactoryMock())
Run Code Online (Sandbox Code Playgroud)
我如何在Go中实现这一目标?
请注意,我可以改变的原型和源代码Transport的功能,但必须保持CarFactory和Car相同的,因为他们是从第三包装中取出
最后一段代码片段是关于Human和Employee的,这导致了混乱.
tha*_*hpk 13
我自己想通了.在Go中模拟结构比使用支持完全后期绑定的其他OOP语言需要更多代码.
自从第三方采用此代码后,此代码必须单独保留
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}
}
Run Code Online (Sandbox Code Playgroud)
由于Go仅支持接口上的后期绑定,因此我必须将Transport接口作为参数而不是struct.
type ICar interface {
Run()
}
type ICarFactory interface {
MakeCar(name string) ICar
}
func Transport(cf ICarFactory) {
...
car := cf.MakeCar("lamborghini")
car.Run()
...
}
Run Code Online (Sandbox Code Playgroud)
这是嘲笑
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}
}
Run Code Online (Sandbox Code Playgroud)
现在我可以轻松使用模拟Transport(CarFactoryMock{}).但是当我尝试调用真正的方法Transport(CarFactory {})时,编译器会显示错误
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
Run Code Online (Sandbox Code Playgroud)
正如消息所说,MakeCar从界面返回一个ICar但真实的MakeCar返回一个Car.Go不允许这样做.要解决这个问题,我必须定义一个包装器,手动转换Car为ICar.
type CarFactoryWrapper struct {
CarFactory
}
func (cf CarFactoryWrapper) MakeCar(name string) ICar {
return cf.CarFactory.MakeCar(name)
}
Run Code Online (Sandbox Code Playgroud)
现在你可以打电话了 Transport(CarFactoryWrapper{CarFactory{}})
这是工作代码https://play.golang.org/p/6YyeZP4tcC
你使用一个接口。
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})
Run Code Online (Sandbox Code Playgroud)
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})
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
12432 次 |
| 最近记录: |