go-spy – spy on mock implementations

Check out go-spy a new mocking library for golang.

While writing tests in golang, we often have to isolate behaviors from one another so that we can test individual functionality without impacting other functionality / behavior or having to do setup all those related behavior.

Programming against interfaces allows us to easily plug dependencies with custom mock object. For example, we might be writing a function for identifying the user from a http request.


func IdentifyUser(d UserLoader, r *http.Request) (*User, error) {
token := r.Header.Get("token")
u, err := d.GetUserByToken(token)
if err != nil {
return nil, err
}
return u, nil
}

Now, if we were not using mocks, we would have to write an implementation of the UserLoader interface which returns correct values depending up on what we are testing. This becomes even more problematic when the interface has several methods which we must implement in order to mock a single method call.

go-spy

Here is how go-spy simplifies spying on mock implementations. First, write a mock implementation which uses go-spy.


type UserLoaderSpy struct {
Spy
}

func (u *UserLoaderSpy) GetUserByToken(token string) (*User, error) {
c := u.Called(token)
return c.Get(0).(*User), c.Error(1)
}

Our mock implementation here is simply passing all incoming calls to the spy which embeded in the UserLoaderSpy struct. The call to Spy.Called() returns a *Call struct which has methods for getting the values to return from our mock implementation.

Now, lets use the UserLoaderSpy:

func TestIdentifyingUserReturnsErrorWhenGetUserByTokenFails(t *testing.T) {
spy := &UserLoaderSpy{}
defer spy.Verify(t)//verifies that all expectations were met
//setup expectation
err := errors.New("dummy error")
spy.When("GetUserByToken", String("testtoken")).Return((*User)(nil), err)//The GetUserByToken method should be called with a string "testtoken" and will return a *User(nil) and our dummy error

r, _ := http.NewRequest("get", "/api/load-book", nil)
r.Header.Set("token", "testtoken")

_, returnedErr := IdentifyUser(spy, r)

if returnedErr != err {
t.Fatal("Expected to fail with error ", err)
}
}

Get go-spy

To install go-spy, run:

go get github.com/nirandas/go-spy

To use go-spy:


import (
. "github.com/nirandas/go-spy"
)

golang variable scope

Here is an interesting golang program which demonstrates a function which accepts an int as string and should return an another int which is an increment of it. nextValue(“4″) should return 5. however, it doesn’t.

http://play.golang.org/p/QMJb6oYqbY


package main

import "fmt"
import "strconv"

func nextValue(n string) int {
v := 0 //new variable v initialized to 0
if n != "" {
v, err := strconv.Atoi(n)
if err != nil {
return v //0
}
}
return v + 1 // return v, which is n++
}

func main() {
fmt.Println("Should print 5. ", nextValue("4")) // but will print 1
}

So, what is going on here? The answer is nested scopes. In golang, variables are scoped to the block. That is, a variable declared in a func is scoped to the func and a variable declared in side an if block is scoped within that if block.

Though we by all means only have one int variable v, to the golang these are two distinct variables who happen to have same name. When we do

v, err := strconv.Atoi(n)

We are declaring two new variables v and err. The variable v here hides the variable initialized to 0 in the outer scope. Hence result of our conversion is not being stored in the first variable which is what actually being returned from the func. There are several ways to fix this issue. For example:

  • Returning the result right after error checking.
  • Predeclaring err variable.
  • Recommended: moving the if condition which checks whether n is “” or not to very beginning of the func and returning 0 or error from it.

    func nextValue(n string) int {
    if n == "" {
    return 0
    }
    v, err := strconv.Atoi(n)
    if err != nil {
    return v //0
    }
    return v + 1 // return v, which is n++
    }

In any case, point to remember here is how golang variable scoping works. And using short declaration syntax := may sometime declare new variables without our intention to do so.

golang mutexes aren’t recursive / re-entrant

golang mutex are a lot different from C# locks. In C#, locking on an object will check whether the current thread has already locked on the object or not. If it has, the locking is successful. However in golang, each mutex.Lock() attempts to lock regardless whether goroutine has already been locked or not.

http://play.golang.org/p/_4Rnp40MEg

package main

import "fmt"
import "sync"
import "time"

func main() {
go func(){
var mu sync.Mutex
mu.Lock()
fmt.Println("first lock")
mu.Lock()
fmt.Println("2nd lock")
mu.Unlock()
mu.Unlock()
fmt.Println("exiting goroutine")
}()

time.Sleep(5*time.Second) // wait 5 seconds
}

In the above program, the 2nd lock call will deadlock as it waits for the lock to be released.

Feature based file organisation for angular.js projects

We mostly see type based organization being used for angular.js projects where files of same type (controllers, services, directives etc) are grouped in to different folders. While this approach is a simple and clean one, it starts to pain quickly.

Slowly I am moving towards feature based folder structure / organization for my angular.js projects. Here files are grouped by feature. For example, I might have a login folder which will contain core services and controllers which relates to login / auth processes (LoginController.js, User.js, LoginService etc).

Each such feature based folder has one file which declares the module and contains the config and run block for the module. Only thing to consider here is that the order in which files are loaded. The file containing the module declaration must be loaded before those files which uses it (defines services, controllers etc on the module).

If you are using lineman or similar grunt tools, this is easily done by reordering the file list. The rule I have is that first include the main application module. then include all module using a pattern similar to “path-to-files/**/*.module.js” and then include individual code file using a catch all pattern “path-to-files/**/*.js”.

This also helps in testing modules separately and clearly helps us to define the modules – using the module feature of angular.js to the fullest.

Another useful trick is to define a constant on each module which contains all required configuration for the module. Example, define a loginConfig constant on login module which will hold URls to the varius API end points, event names triggered by the module and so on. It also helps us to easily mock the config object during testing.

ng-socket – an angular.js wrapper for HTML5 WebSocket

More documentation and updates to be followed. Especially, dependency on sockjs will be made optional.

Take a look at ng-socket an Angular JS module which can be used to integrate SockJS in to your angular JS projects.

Features:
* Incoming messages are broadcasted on $rootScope.
* Can specify custom message parser and formatter for integrating in to your custom protocol.
* Rate limits broadcasting of incoming messages to twice per second and wraps the broadcast in $rootScope.$apply.
* Can re-connect on disconnects with configurable interval.
* Queues sent messages if socket is not yet connected and sends them on connection.
* Broadcasts open event on connection enabling users to send special messages before other messages (authentication etc).
* broadcastPrefix configuration option allows all broadcasted messages including received from server to be prefixed. Default is “$socket.”.

Project is a lineman app. You can either clone the repo and get the app/ng-socket.js or run lineman build and get the minified version from dist/js/ng-socket.js.