Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I recently rewrote a piece of software to practice unit-testing. I decided to constrain myself and do dependency-free code, so I can do better and easier tests. I came to the following solution while writing the methods that deal with files :

/* foo.go */
package main

import (
    "io"
    "os"
)

type Foo struct {
    reader io.Reader
}

func NewFoo(filename string) (*Foo, error) {
    return newFoo(filename, os.Open)
}

type opener func(string) (*os.File, error)

func newFoo(filename string, open opener) (*Foo, error) {
    file, err := open(filename)
    if err != nil {
        return nil, err
    }

    return &Foo{
        reader: file,
    }, nil
}

And here is the test file that come along.

/* foo_test.go */
package main

import (
    "errors"
    "os"
    "testing"
)

func TestNewFooOpeningError(t *testing.T) {
    f, err := newFoo("", func(_ string) (*os.File, error) {
        return nil, errors.New("openning error")
    })

    if f != nil {
        t.Error(f, "!=", nil)
    }

    if err.Error() != "openning error" {
        t.Error(err.Error(), "!=", "openning error")
    }
}

func TestNewFooOK(t *testing.T) {
    f, err := newFoo("", func(_ string) (*os.File, error) {
        return nil, nil
    })

    if f == nil {
        t.Error(f, "==", nil)
    }

    if err != nil {
        t.Error(err.Error(), "!=", nil)
    }
}

It looks ok for me, but when there is more than one method to fake, I feel it a bit messy/ugly/unreadable/"pick your own adjective"

My questions are the following :

  1. Is this pattern sane ?
  2. If not, do you have any saner alternative ?
  3. Do you recommend a particular testing good practice for this cases ?
share|improve this question

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.