英文:
Testing a function which uses fmt.Scanf() in Go
问题
我想为包含对 fmt.Scanf()
的调用的函数编写测试,但是在传递必需参数给函数时遇到了问题。
有没有更好的方法来解决这个问题,或者我需要模拟 fmt.Scanf()
?
要测试的函数在这里:
https://github.com/apsdehal/Konsoole/blob/master/parser.go#L28
// 通过查找所有可用设备来初始化网络接口
// 将它们显示给用户,最后根据用户选择其中一个
func Init() *pcap.Pcap {
devices, err := pcap.Findalldevs()
if err != nil {
fmt.Fprintf(errWriter, "[-] Error, pcap failed to iniaitilize")
}
if len(devices) == 0 {
fmt.Fprintf(errWriter, "[-] No devices found, quitting!")
os.Exit(1)
}
fmt.Println("Select one of the devices:")
var i int = 1
for _, x := range devices {
fmt.Println(i, x.Name)
i++
}
var index int
fmt.Scanf("%d", &index)
handle, err := pcap.Openlive(devices[index-1].Name, 65535, true, 0)
if err != nil {
fmt.Fprintf(errWriter, "Konsoole: %s\n", err)
errWriter.Flush()
}
return handle
}
英文:
I want to write test for function which includes a call to fmt.Scanf()
, but I am having problem in passing the required parameter to function.
Is there a better way to do this or I need to mock fmt.Scanf()
Function to be tested is given here:
https://github.com/apsdehal/Konsoole/blob/master/parser.go#L28
// Initializes the network interface by finding all the available devices
// displays them to user and finally selects one of them as per the user
func Init() *pcap.Pcap {
devices, err := pcap.Findalldevs()
if err != nil {
fmt.Fprintf(errWriter, "[-] Error, pcap failed to iniaitilize")
}
if len(devices) == 0 {
fmt.Fprintf(errWriter, "[-] No devices found, quitting!")
os.Exit(1)
}
fmt.Println("Select one of the devices:")
var i int = 1
for _, x := range devices {
fmt.Println(i, x.Name)
i++
}
var index int
fmt.Scanf("%d", &index)
handle, err := pcap.Openlive(devices[index-1].Name, 65535, true, 0)
if err != nil {
fmt.Fprintf(errWriter, "Konsoole: %s\n", err)
errWriter.Flush()
}
return handle
}
答案1
得分: 3
理论上可以通过将os.Stdin
的值与其他os.File
进行热交换来改变Scanf
的行为。不过,我不会特别推荐仅出于测试目的而这样做。
一个更好的选择是让你的Init
函数接受一个io.Reader
参数,然后将其传递给Fscanf
函数。
然而,总体而言,最好尽可能地将设备初始化代码与输入分离。这可能意味着有一个返回设备列表的函数和一个设备打开函数。你只需要在实时/主要代码中提示进行选择。
英文:
It's theoretically possible to change the behavior of Scanf
by hotswapping the value of os.Stdin
with some other os.File
. I wouldn't particularly recommend it just for testing purposes, though.
A better option would just be to make your Init
take in an io.Reader
that you pass to Fscanf
.
Overall, however, it would likely be better to separate your device initialization code from your input as much as possible. This probably means having a device list returning function and a device opening function. You only need to prompt for selection in live/main code.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论