I have an app (epazote) that once starts runs forever but I want to test some values before it blocks/waits until ctrl+c is pressed or is killed.
Here is an small example: 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")
}
I would like to know if is posible to ignore some parts of the code while testing, or how to test this cases, I have implemented an interface, in this case for testing AddString
that helped me to test some parts but have no idea of how to avoid the "block" and test.
Any ideas?
Update: Putting the code inside the loop Addstring
in another function works but only for testing that function, but If I want to do a full code coverage, I still need to check/test the blocking part, for example how to test that is properly behaving when receiving ctrl+c or a kill -HUP
, I was thinking on maybe creating a fake signal.Notify
but don't know how to overwrite imported packages in case that could work.
Introduce test delegates into your code.
Extract your loop into a function that takes 2 functions as arguments: onBeginEvent and onEndEvent. The functions signatures shall take:
In the beginning of your loop you call OnBegingEvent(counter, currentState); than your code does its normal work and in the end you call OnEndEvent(counter, currentState); Presumably your code has changed currentState.
In production you could use an empty implementation of the function delegates or implement nil check in your loop.
You can use this model to put as many checks of your processing algorithms as you want. Let's say you have 5 checks. Now you look back at it and realize that's becoming too hard. You create an Interface that defines your callback functions. These callback functions are a powerful method of changing your service behavior. You step back one more time and realize that interface is actually your "service's policy" ;)
Once you take that route you will want to stop your infinite loop somehow. If you want a tight control within a test case you could take a 3rd function delegate that returns true if it is time to quit from the loop. Shared variable is an option to control quit condition.
This is certainly a higher level of testing than unit testing and it is necessary in complex services.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With