Go assert.Equal some interface with time.Time object inside - unit-testing

I am trying to check if the returned data equals the expectation
Here is my function:
func extractData(payload string) (interface{}, time.Time, error) {
eventTime := gjson.Get(payload, "data.eventDateTime").String()
dateTime, err := time.Parse("2006-01-02T15:04:05-07:00", eventTime)
if err != nil {
return nil, time.Time{}, fmt.Errorf("Date Time Error: %w", err)
}
body := data.Body{
EventTime: dateTime,
}
return body, dateTime, nil
}
This is the unit test I wrote for it:
func TestExtractData(t *testing.T) {
tests := []struct {
Name string
Payload string
ExpectedOutput interface{}
}{
{
Name: "test-2",
Payload: "{\"data\":\"2020-11-02T10:44:48+01:00\"}",
ExpectedOutput: data.Body{
EventTime: time.Date(2020, 11, 2, 10, 44, 48, 0, time.FixedZone("CET", 3600)),
},
},
}
for _, tt := range tests {
t.Run(tt.Name, func(t *testing.T) {
data, _, _ := extractData(tt.Payload)
assert.Equal(t, tt.ExpectedOutput, data)
})
}
}
The test is failing, it outputs:
{ 2020-11-02 10:44:48 +0100 CET} does not equal { 2020-11-02 10:44:48 +0100 CET}
I believe the problem is in TimeZone, but I struggles to write the test code.
I don't want to test it using time.Equal, because my data.Body does not always contains the eventTime element.
I tried (by temporary use type not interface):
if !tt.ExpectedOutput.EventTime.Equal(data.EventTime) {
//throw error
}
and it works.
I also i tried:
if !reflect.DeepEqual(tt.ExpectedOutput.EventTime, data.EventTime) {
t.Errorf("extractData() output = %v, want = %v",data,tt.ExpectedOutput)
}
The code above fails.

You're partially correct that the time zone can make two time.Time instances representing the same time fail equality. It can also be that because since go 1.9, time.Time also includes wall time to make all comparisons safe, time.Time literals such as your ExpectedOutput field will never contain this wall time, so are "different".
Your best solution is probably to compare the time using assert.WithinDuration() (I assume you are using github.com/stretchr/testify/assert?):
package kata
import (
"testing"
"time"
"github.com/stretchr/testify/assert"
)
func TestTime(t *testing.T) {
format := "2006-01-02 15:04:05.999999999 -0700 MST"
time1 := time.Now()
time2, err := time.Parse(format, time1.Format(format))
assert.NoError(t, err)
t.Log(time1)
t.Log(time2)
assert.Equal(t, time1, time2) // fails
assert.WithinDuration(t, time1, time2, 0) // passes
}

Related

assert: mock: I don't know what to return (even if I've declared the mock function & the return)

I use Testify to create a unit test for my golang app. I need to create a unit test for this function where it calls a variadic function (function with trailing arguments). I encountered an error when I test it. I'm actually not sure if the error is because of the trailing argument itself or not, but I feel like there's something wrong with the mock.
// svc/callThisFunction.go
// data type of args is []sqkit.SelectOption
func CallThisFunction(ctx context.Context, args ...sqkit.SelectFunctiom) (result string, err error) {
return result, nil
}
// svc/functionToTest.go
// This is the function that I wanna test
func FunctionToTest(ctx context.Context, id int64) (result string, err error) {
args := []sqkit.SelectOption{
sqkit.Where{
fmt.Sprintf("id = %d", id),
},
}
newResult, err := callThisFunctionService.CallThisFunction(ctx, args)
if err != nil {
return newResult, err
}
return newResult, nil
}
// svc/functionToTest_test.go
func Test_FunctionToTest(t *testing.T) {
testCase := []struct {
name string
id int64
onCallThisFunctionMock func(callThisFunctionSvc *mocks.CallThisFunctionSvc)
expectedResult string
wantError bool
expectedError error
}{
{
name: "Success",
id: 1,
onCallThisFunctionMock: func(callThisFunctionSvc *mocks.CallThisFunctionSvc) {
// NOTE: I've created 2 different versions (used separately, not at the same), using mock.Anything() and using actual arguments
// Both of these give the same errors
// Using actual arguments
args := []sqkit.SelectOption{
sqkit.Where{
fmt.Sprintf("id = %d", 1},
},
}
callThisFunctionSvc.On("CallThisFunction", context.Background(), args).Return("Success", nil)
// Using mock.Anything
callThisFunctionSvc.On("CallThisFunction", context.Background(), mock.Anything).Return("Success", nil)
}
}
}
for _, tc := range testCases {
var callThisFunctionSvc = new(mocks.CallThisFunctionSvc)
tc.onCallThisFunctionMock(callThisFunctionSvc)
svc := &svc.FunctionToTest{
CallThisFunction: callThisFunctionSvc,
}
actualResult, actualError := svc.FunctionToTest(context.Background(), tc.id)
if tc.wantEror {
require.Error(t, actualError, tc.expectedError)
} else {
require.NoError(t, actualError)
}
require.Equal(t, tc.expectedResult, actualResult)
}
}
This is the error it gives
=== RUN Test_GenerateDocument
--- FAIL: Test_GenerateDocument (0.00s)
panic:
assert: mock: I don't know what to return because the method call was unexpected.
Either do Mock.On("CallThisFunction").Return(...) first, or remove the GetTemplates() call.
This method was unexpected:
CallThisFunction(*context.emptyCtx,sqkit.Where)
0: (*context.emptyCtx)(0xc0000a4010)
1: sqkit.Where{"id = 1"}
Usually, when I encountered an error like this, it's because I haven't defined the return values of the function calls inside the function I wanna test. But this time I've created it, but it somehow can't read the return. Any idea why?
The error indicates you called CallThisFuncion with params (context.Context, sqkit.Where), but your example is using and setting the expectation for (context.Context, []sqkit.Option). The example with mock.Anything should work, but I believe it's failing because of the context. You'll need to set the expectation with the same context you're passing down. If FunctionToTest is going to be altering the context, I believe you'll need to use mock.Anything instead.
func Test_FunctionToTest(t *testing.T) {
testCase := []struct {
name string
id int64
onCallThisFunctionMock func(context.Context, *mocks.CallThisFunctionSvc)
expectedResult string
wantError bool
expectedError error
}{
{
name: "Success",
id: 1,
onCallThisFunctionMock: func(ctx context.Context, callThisFunctionSvc *mocks.CallThisFunctionSvc) {
args := []sqkit.SelectOption{
sqkit.Where{
fmt.Sprintf("id = %d", 1},
},
}
callThisFunctionSvc.On("CallThisFunction", ctx, args).Return("Success", nil)
}
}
}
for _, tc := range testCases {
var callThisFunctionSvc = new(mocks.CallThisFunctionSvc)
var ctx = context.Background()
tc.onCallThisFunctionMock(ctx, callThisFunctionSvc)
svc := &svc.FunctionToTest{
CallThisFunction: callThisFunctionSvc,
}
actualResult, actualError := svc.FunctionToTest(ctx, tc.id)
if tc.wantEror {
require.Error(t, actualError, tc.expectedError)
} else {
require.NoError(t, actualError)
}
require.Equal(t, tc.expectedResult, actualResult)
}
}
If you want to ensure a context.Context was passed as the first parameter but don't care what context, you could use AnythingOfType.
callThisFunctionSvc.On("CallThisFunction", mock.AnythingOfType("context.Context"), args).Return("Success", nil)

How to mock a nested client in test

I am building a simple function that calls an API that returns a Post using GraphQL (https://github.com/machinebox/graphql). I wrapped the logic in a service that looks like this:
type Client struct {
gcl graphqlClient
}
type graphqlClient interface {
Run(ctx context.Context, req *graphql.Request, resp interface{}) error
}
func (c *Client) GetPost(id string) (*Post, error) {
req := graphql.NewRequest(`
query($id: String!) {
getPost(id: $id) {
id
title
}
}
`)
req.Var("id", id)
var resp getPostResponse
if err := c.gcl.Run(ctx, req, &resp); err != nil {
return nil, err
}
return resp.Post, nil
}
Now I'd like to add test tables for the GetPost function with a fail case when id is set to empty string which causes an error in the downstream call c.gcl.Run.
What I am struggling with is the way the gcl client can be mocked and forced to return the error (when no real API call happens).
My test so far:
package apiClient
import (
"context"
"errors"
"github.com/aws/aws-sdk-go/aws"
"github.com/google/go-cmp/cmp"
"github.com/machinebox/graphql"
"testing"
)
type graphqlClientMock struct {
graphqlClient
HasError bool
Response interface{}
}
func (g graphqlClientMock) Run(_ context.Context, _ *graphql.Request, response interface{}) error {
if g.HasError {
return errors.New("")
}
response = g.Response
return nil
}
func newTestClient(hasError bool, response interface{}) *Client {
return &Client{
gcl: graphqlClientMock{
HasError: hasError,
Response: response,
},
}
}
func TestClient_GetPost(t *testing.T) {
tt := []struct{
name string
id string
post *Post
hasError bool
response getPostResponse
}{
{
name: "empty id",
id: "",
post: nil,
hasError: true,
},
{
name: "existing post",
id: "123",
post: &Post{id: aws.String("123")},
response: getPostResponse{
Post: &Post{id: aws.String("123")},
},
},
}
for _, tc := range tt {
t.Run(tc.name, func(t *testing.T) {
client := newTestClient(tc.hasError, tc.response)
post, err := client.GetPost(tc.id)
if err != nil {
if tc.hasError == false {
t.Error("unexpected error")
}
} else {
if tc.hasError == true {
t.Error("expected error")
}
if cmp.Equal(post, &tc.post) == false {
t.Errorf("Response data do not match: %s", cmp.Diff(post, tc.post))
}
}
})
}
}
I am not sure if passing the response to the mock like this is the right way to do it. Also, I'm struggling to set the right value to the response, since an interface{} type is passed and I don't know how to convert it to the getPostResponse and set the value to Post there.
Your test cases should not go beyond the implementation. I'm specifically referring to the empty-vs-nonempty input or any kind of input really.
Let's take a look at the code you want to test:
func (c *Client) GetPost(id string) (*Post, error) {
req := graphql.NewRequest(`
query($id: String!) {
getPost(id: $id) {
id
title
}
}
`)
req.Var("id", id)
var resp getPostResponse
if err := c.gcl.Run(ctx, req, &resp); err != nil {
return nil, err
}
return resp.Post, nil
}
Nothing in the implementation above is doing anything based on the id parameter value and therefore nothing in your tests for this piece of code should really care about what input is passed in, if it is irrelevant to the implementation it should also be irrelevant to the tests.
Your GetPost has basically two code branches that are taken based on a single factor, i.e. the "nilness" of the returned err variable. This means that as far as your implementation is concerned there are only two possible outcomes, based on what err value Run returns, and therefore there should only be two test cases, a 3rd or 4th test case would be just a variation, if not an outright copy, of the first two.
Your test client is also doing some unnecessary stuff, the main one being its name, i.e. what you have there is not a mock so calling it that is not helpful. Mocks usually do a lot more than just return predefined values, they ensure that methods are called, in the expected order and with the expected arguments, etc. And actually you don't need a mock here at all so it's a good thing it isn't one.
With that in mind, here's what I would suggest you do with your test client.
type testGraphqlClient struct {
resp interface{} // non-pointer value of the desired response, or nil
err error // the error to be returned by Run, or nil
}
func (g testGraphqlClient) Run(_ context.Context, _ *graphql.Request, resp interface{}) error {
if g.err != nil {
return g.err
}
if g.resp != nil {
// use reflection to set the passed in response value
// (i haven't tested this so there may be a bug or two)
reflect.ValueOf(resp).Elem().Set(reflect.ValueOf(g.resp))
}
return nil
}
... and here are the necessary test cases, all two of them:
func TestClient_GetPost(t *testing.T) {
tests := []struct {
name string
post *Post
err error
client testGraphqlClient
}{{
name: "return error from client",
err: errors.New("bad input"),
client: testGraphqlClient{err: errors.New("bad input")},
}, {
name: "return post from client",
post: &Post{id: aws.String("123")},
client: testGraphqlClient{resp: getPostResponse{Post: &Post{id: aws.String("123")}}},
}}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
client := Client{gql: tt.client}
post, err := client.GetPost("whatever")
if !cmp.Equal(err, tt.err) {
t.Errorf("got error=%v want error=%v", err, tt.err)
}
if !cmp.Equal(post, tt.post) {
t.Errorf("got post=%v want post=%v", post, tt.post)
}
})
}
}
... there's a bit of repetition going on here, the need to spell out the post and err twice but that's a small price to pay when compared to a more sophisticated/complicated test setup that would populate the test client from the test case's expected output fields.
Addendum:
If you were to update GetPost in such a way that it checks for the empty id and returns an error before it sends a request to graphql then your initial setup would make much more sense:
func (c *Client) GetPost(id string) (*Post, error) {
if id == "" {
return nil, errors.New("empty id")
}
req := graphql.NewRequest(`
query($id: String!) {
getPost(id: $id) {
id
title
}
}
`)
req.Var("id", id)
var resp getPostResponse
if err := c.gcl.Run(ctx, req, &resp); err != nil {
return nil, err
}
return resp.Post, nil
}
... and updating the test cases accordingly:
func TestClient_GetPost(t *testing.T) {
tests := []struct {
name string
id string
post *Post
err error
client testGraphqlClient
}{{
name: "return empty id error",
id: "",
err: errors.New("empty id"),
client: testGraphqlClient{},
}, {
name: "return error from client",
id: "nonemptyid",
err: errors.New("bad input"),
client: testGraphqlClient{err: errors.New("bad input")},
}, {
name: "return post from client",
id: "nonemptyid",
post: &Post{id: aws.String("123")},
client: testGraphqlClient{resp: getPostResponse{Post: &Post{id: aws.String("123")}}},
}}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
client := Client{gql: tt.client}
post, err := client.GetPost(tt.id)
if !cmp.Equal(err, tt.err) {
t.Errorf("got error=%v want error=%v", err, tt.err)
}
if !cmp.Equal(post, tt.post) {
t.Errorf("got post=%v want post=%v", post, tt.post)
}
})
}
}

Using interface for testing like dependency injection

I use the following code which works ok.
This is working example
https://play.golang.org/p/wjvJtDNvJAQ
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
type requester interface {
HTTPRequest(c string, i string, mtd string, url string) (p []byte, e error)
}
type impl struct {
client *http.Client
}
// ----This is the function which I need to mock
func (s *ServiceInfo) wrapperFN() {
// Function 1 - get the values
v1, v2 := s.json.parseJson()
// call to http function
s.req.HTTPRequest(v1, v2, "POST", "http://www.mocky.io/v2/5c20eccc2e00005c001e0c84")
}
func (i impl) HTTPRequest(c string, ci string, mtd string, url string) (p []byte, e error) {
req, err := http.NewRequest(mtd, url, nil)
if err != nil {
return nil, err
}
req.SetBasicAuth(c, ci)
res, err := i.client.Do(req)
if err != nil {
return nil, err
}
token, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, err
}
defer res.Body.Close()
fmt.Println("success")
return token, nil
}
type parser interface {
parseJson() (string, string)
}
type jsonP struct {
data string
}
func (s jsonP) parseJson() (string, string) {
var result map[string]interface{}
json.Unmarshal([]byte(s.data), &result)
b := result["person"].(map[string]interface{})
for key, value := range b {
return key, value.(string)
}
return "", ""
}
type ServiceInfo struct {
req requester
json parser
}
// When in production pass in concrete implementations.
func NewServiceInfo(http requester, json parser) *ServiceInfo {
return &ServiceInfo{
req: http,
json: json,
}
}
func main() {
httpClient := http.Client{}
js := `{"person":{"p1":"username","p2":"password"},"customers":"10"}`
j := jsonP{data: js}
s := NewServiceInfo(impl{client: &httpClient}, j)
s.wrapperFN()
}
Now i want to test it wrapperFN , what I try I've changed the code to use interface , which works.
This is just example to give a point ( the real code much more complicated)
The problem that I dont understand how to mock function inside wrapperFN like parseJson() , in the real world warpperFN contains several function which I need to mock ,because just calling them in the test will provide error.
How it's best to mock function like parseJson() & HTTPRequest? and assume that inside wrapperFN there is additional functions which is not related...
I need to know if this is the best practice for testing function.
This is the test (which im not sure how to make it right)
package main
import (
"net/http"
"net/http/httptest"
"testing"
)
func TestServiceInfo_wrapperFN(t *testing.T) {
tests := []struct {
name string
s *ServiceInfo
}{
{
name: "wrapper test",
s: &ServiceInfo{},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var testHandler http.Handler
srv := httptest.NewServer(testHandler)
defer srv.Close()
iReq := &impl{
client: srv.Client(),
}
v := &ServiceInfo{http: *iReq}
v.wrapperFN()
})
}
}

Table-driven test for file creation

I got an example from #volker about table driven test like following
But currently I miss what I should put in the real test, this test is using byte, currently im not sure what to put in the args and the expected []byte,
e.g. I want to check that in the file there is 2 new line and then application entry, how can I do it without the need to create the real file and parse it?
type Models struct {
name string
vtype string
contentType string
}
func setFile(file io.Writer, appStr Models) {
fmt.Fprint(file, "1.0")
fmt.Fprint(file, "Created-By: application generation process")
for _, mod := range appStr.Modules {
fmt.Fprint(file, "\n")
fmt.Fprint(file, "\n")
fmt.Fprint(file, appStr.vtype) //"userApp"
fmt.Fprint(file, "\n")
fmt.Fprint(file, appStr.name) //"applicationValue"
fmt.Fprint(file, "\n")
fmt.Fprint(file, appStr.contentType)//"ContentType"
}
}
func Test_setFile(t *testing.T) {
type args struct {
appStr models.App
}
var tests []struct {
name string
args args
expected []byte
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
b := &bytes.Buffer{}
setFile(b, tt.args.AppStr)
if !bytes.Equal(b.Bytes(), tt.expected) {
t.Error("somewhat bad happen")
}
})
}
}
I read and understand the following example but not for byte and file
https://medium.com/#virup/how-to-write-concise-tests-table-driven-tests-ed672c502ae4
If you are only checking for the static content at the beginning, then you really only need one test. It would look something like this:
func Test_setFile(t *testing.T) {
type args struct {
appStr models.App
}
var tests []struct {
name string
args args
expected []byte
}{
name: 'Test Static Content',
args: args{appStr: 'Some String'},
expected: []byte(fmt.Sprintf("%s%s%s", NEW_LINE, NEW_LINE, "Application")),
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
b := &bytes.Buffer{}
setFile(b, tt.args.AppStr)
if !bytes.Equal(b.Bytes(), tt.expected) {
t.Error("somewhat bad happen")
}
})
}
}
Although, since you only have one case for this test, there really isn't a need to use table driven tests here. You could clean it up to look something like this:
func Test_setFile(t *testing.T) {
b := &bytes.Buffer{}
setFile(b, 'Some String')
want := []byte(fmt.Sprintf("%s%s%s", NEW_LINE, NEW_LINE, "Application"))
got := b.Bytes()
if !bytes.Equal(want, got) {
t.Errorf("want: %s got: %s", want, got)
}
}

How to mock exec.Command for multiple unit tests in Go lang?

I just learnt unit testing functions that uses exec.Command() i.e., mocking exec.Command(). I went ahead to added more unit cases, but running into issues of not able to mock the output for different scenarios.
Here is a sample code hello.go I'm trying to test...
package main
import (
"fmt"
"os/exec"
)
var execCommand = exec.Command
func printDate() ([]byte, error) {
cmd := execCommand("date")
out, err := cmd.CombinedOutput()
return out, err
}
func main() {
fmt.Printf("hello, world\n")
fmt.Println(printDate())
}
Below is the test code hello_test.go...
package main
import (
"fmt"
"os"
"os/exec"
"testing"
)
var mockedExitStatus = 1
var mockedDate = "Sun Aug 20"
var expDate = "Sun Aug 20"
func fakeExecCommand(command string, args ...string) *exec.Cmd {
cs := []string{"-test.run=TestHelperProcess", "--", command}
cs = append(cs, args...)
cmd := exec.Command(os.Args[0], cs...)
cmd.Env = []string{"GO_WANT_HELPER_PROCESS=1"}
return cmd
}
func TestHelperProcess(t *testing.T) {
if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" {
return
}
// println("Mocked Data:", mockedDate)
fmt.Fprintf(os.Stdout, mockedDate)
os.Exit(mockedExitStatus)
}
func TestPrintDate(t *testing.T) {
execCommand = fakeExecCommand
defer func() { execCommand = exec.Command }()
out, err := printDate()
print("Std out: ", string(out))
if err != nil {
t.Errorf("Expected nil error, got %#v", err)
}
if string(out) != expDate {
t.Errorf("Expected %q, got %q", expDate, string(out))
}
}
func TestPrintDateUnableToRunError(t *testing.T) {
execCommand = fakeExecCommand
defer func() { execCommand = exec.Command }()
mockedExitStatus = 1
mockedDate = "Unable to run date command"
expDate = "Unable to run date command"
out, err := printDate()
print("Std out: ", string(out))
if err != nil {
t.Errorf("Expected nil error, got %#v", err)
}
if string(out) != expDate {
t.Errorf("Expected %q, got %q", expDate, string(out))
}
}
go test fails for the second test TestPrintDateUnableToRunError...
$ go test hello
Std out: Sun Aug 20Std out: Sun Aug 20--- FAIL: TestPrintDateTomorrow (0.01s)
hello_test.go:62: Expected "Unable to run date command", got "Sun Aug 20"
FAIL
FAIL hello 0.017s
Even though I'm trying to set the global mockedDate value inside the test case, it's still getting the global value that it was initialized with. Is the global value not getting set? Or the changes to that global var is not getting updated in TestHelperProcess?
I got the solution for this...
Is the global value not getting set? Or the changes to that global var is not getting updated in TestHelperProcess?
Since in TestPrintDate(), fakeExecCommand is called instead of exec.Command, and calling fakeExecCommand runs go test to run only TestHelperProcess(), it's altogether a new invocation where only TestHelperProcess() will be executed. Since only TestHelperProcess() is called, the global variables aren't being set.
The solution would be to set the Env in the fakeExecCommand, and retrieve that in TestHelperProcess() and return those values.
PS> TestHelperProcess is renamed to TestExecCommandHelper, And few variables are renamed.
package main
import (
"fmt"
"os"
"os/exec"
"strconv"
"testing"
)
var mockedExitStatus = 0
var mockedStdout string
func fakeExecCommand(command string, args ...string) *exec.Cmd {
cs := []string{"-test.run=TestExecCommandHelper", "--", command}
cs = append(cs, args...)
cmd := exec.Command(os.Args[0], cs...)
es := strconv.Itoa(mockedExitStatus)
cmd.Env = []string{"GO_WANT_HELPER_PROCESS=1",
"STDOUT=" + mockedStdout,
"EXIT_STATUS=" + es}
return cmd
}
func TestExecCommandHelper(t *testing.T) {
if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" {
return
}
// println("Mocked stdout:", os.Getenv("STDOUT"))
fmt.Fprintf(os.Stdout, os.Getenv("STDOUT"))
i, _ := strconv.Atoi(os.Getenv("EXIT_STATUS"))
os.Exit(i)
}
func TestPrintDate(t *testing.T) {
mockedExitStatus = 1
mockedStdout = "Sun Aug 201"
execCommand = fakeExecCommand
defer func() { execCommand = exec.Command }()
expDate := "Sun Aug 20"
out, _ := printDate()
if string(out) != expDate {
t.Errorf("Expected %q, got %q", expDate, string(out))
}
}
func TestPrintDateUnableToRunError(t *testing.T) {
mockedExitStatus = 1
mockedStdout = "Unable to run date command"
execCommand = fakeExecCommand
defer func() { execCommand = exec.Command }()
expDate := "Unable to run date command"
out, _ := printDate()
// println("Stdout: ", string(out))
if string(out) != expDate {
t.Errorf("Expected %q, got %q", expDate, string(out))
}
}
go test results as below...
(Purposely failing one test to show that the mock is working properly).
go test hello
--- FAIL: TestPrintDate (0.01s)
hello_test.go:45: Expected "Sun Aug 20", got "Sun Aug 201"
FAIL
FAIL hello 0.018s
Based on the code you've posted, the mockedDate variable doesn't do anything. Neither the test, nor the call to printDate() are utilizing it, so the TestPrintDateUnableToRunError() test performs just like the tests before it.
If you were to add functionality to the printDate() function to return string of "Unable to run date command" (when that is the case), then your condition on line 62 would pass. That said, such checks should be unnecessary, when you have an error in the return values from printDate(). If the returned error is non-nil, the returned output string should be expected to be invalid (or empty, "").
I can't tell how you really want printDate() to fail, but as it stands, there's no way for it to return the values you're expecting in TestPrintDateUnableToRunError().