如何测试永远循环的代码

时间:2016-01-25 23:14:08

标签: unit-testing go

我有一个应用程序(epazote),一旦开始永远运行,但我想在阻止/等待之前测试一些值,直到 ctrl + c 为被迫或被杀。

以下是一个小例子:http://play.golang.org/p/t0spQRJB36

package main

import (
    "fmt"
    "os"
    "os/signal"
)

type IAddString interface {
    AddString(string)
}

type addString struct{}

func (self *addString) AddString(s string) {
    fmt.Println(s)
}

func block(a IAddString, s string) {

    // test this
    a.AddString(s)


    // ignore this while testing
    block := make(chan os.Signal)
    signal.Notify(block, os.Interrupt, os.Kill)

    for {
        signalType := <-block
        switch signalType {

        default:
            signal.Stop(block)
            fmt.Printf("%q signal received.", signalType)
            os.Exit(0)
        }
    }
}

func main() {
    a := &addString{}
    block(a, "foo")
}

我想知道在测试时是否可以忽略代码的某些部分,或者如何测试这种情况,我已经实现了一个接口,在这种情况下用于测试AddString帮助我测试一些部分,但不知道如何避免“阻止”和测试。

有什么想法吗?

更新:将代码放在循环Addstring中的另一个函数中,但仅用于测试该函数,但如果我想要完整的代码覆盖率,我仍需要检查/测试阻塞部分,例如当接收 ctrl + c kill -HUP时如何测试它是否正常运行,我在考虑创建一个假的signal.Notify但不知道如何覆盖导入的包以防万一。

2 个答案:

答案 0 :(得分:4)

是的,这是可能的。将循环内部的代码放在一个单独的函数中,并在没有循环的情况下对该函数进行单元测试。

答案 1 :(得分:1)

将测试代表介绍到您的代码中。

将循环提取到一个函数中,该函数将2个函数作为参数:onBeginEvent和onEndEvent。功能签名应采取:

  • 声明您要在测试用例内部进行检查
  • 可选:循环编号的计数器(这样您就可以识别每个循环)。它是可选的,因为实际的委托实现可以计算它自己调用的次数。

在循环开始时调用OnBegingEvent(counter,currentState);比你的代码正常工作,最后调用OnEndEvent(counter,currentState);大概你的代码改变了currentState。

在生产中,您可以使用函数委托的空实现,或在循环中实现nil检查。

您可以使用此模型根据需要对处理算法进行尽可能多的检查。假设您有5张支票。现在你回顾它并意识到这变得太难了。您创建一个定义回调函数的接口。这些回调函数是一种更改服务行为的强大方法。你再退一步,意识到界面实际上是你的“服务政策”;)

一旦你采取了这条路线,你就会想要以某种方式阻止你的无限循环。如果你想在测试用例中进行严格的控制,你可以使用第3个函数委托,如果是从循环中退出的话,它返回true。共享变量是控制退出条件的选项。

这肯定是比单元测试更高级别的测试,并且在复杂服务中是必要的。