如何测试延迟执行的 Go 语句?

huangapple go评论78阅读模式
英文:

How to test deferred Go statements?

问题

如何测试doStuff函数?(Playground:http://play.golang.org/p/aPFSlaBLgX)

package myPackage

var locked = false

func doStuff() {
    defer unlock()
    lock()
    // some task that can cause errors
    // need to test if lock was really unlocked
    // this is just a simple example, things can go complex on real world
    panic("!")
}

func lock() {
    locked = true
}

func unlock() {
    locked = false
}

换句话说,如何测试使用defer语句的代码?应该使用什么通用策略来测试延迟调用?如果没有通用做法,如何测试这个特定的代码?

PS:Go playground只允许package main

英文:

How can I test doStuff function? (Playground: http://play.golang.org/p/aPFSlaBLgX)

package myPackage

var locked = false

func doStuff() {
    defer unlock()
    lock()
    // some task that can cause errors
    // need to test if lock was really unlocked
    // this is just a simple example, things can go complex on real world
    panic("!")
}

func lock() {
    locked = true
}

func unlock() {
    locked = false
}

In other words: how to test code that uses defer statements? What general strategies should be used to test deferred calls? If there are no general practice, how to test this specific code?

PS: Go playground only allows package main

答案1

得分: 0

TL;DR

为了测试恐慌状态,断言应该被延迟执行。

看起来为了测试panic状态,我们应该将测试断言语句放在defer中:

package myPackage

import "testing"

func TestLock(t *testing.T) {
    defer func (){
        if locked == true {
            t.Error("Expected locked to be false but got locked =", locked)
        }
    }() // 在恐慌状态下执行断言 ↑
    defer func (){ recover() }() // 从恐慌中恢复 ↑
    doStuff() // 这会引发恐慌,代码执行将会跳转到上面 ↑
    // 当然,执行永远不会到达下面这行 ---
    // 不要在这里放置断言
}

这是因为在doStuff()下面没有代码被执行,因为我们模拟了一个panic,所以断言应该被延迟执行,这样它们就在"恐慌的作用域"中。

英文:

TL;DR

> To test a panicked state the assertions should be deffered

Looks like that to test a panic state we should defer the test assertions:

package myPackage

import "testing"

func TestLock(t *testing.T) {
    defer func (){
        if locked == true {
            t.Error("Expected locked to be false but got locked =", locked)
        }
    }() // do assertions on panicked state ↑
    defer func (){ recover() }() // recover from panic ↑
    doStuff() // this will panic and code execution will flow up ↑
    // and, of course, execution will never reach below this line ---
    // don't put assertions here
}

This happens because no code is executed below doStuff() since we are simulating a panic, therefore the assertions should be deferred so they will be on "panicked scope".

huangapple
  • 本文由 发表于 2014年12月24日 10:29:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/27630675.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定