-2

I'm testing an API where I need to "login" and get an Auth Token that I store in a struct and pass to my functions. I'm trying to write a '_test.go' file, but the Auth Token is not getting passed to the testing functions, and I'm not sure why. All the online example test files are very simplistic, and I can't find any example that's even close to what I am trying to do here -- but then again, it could be my Google Foo is weak today..

Here's the code:

package myapi

import (
    "flag"
    "fmt"
    "os"
    "testing"
)

// The Global var that needs to be read/write-able from all the testing func's
var d Device

func TestMain(m *testing.M) {
    // --- Log into our test device ---
    d.Address = os.Getenv("THEIP")
    d.Username = "admin"
    d.Password = "password"
    d, err := d.Login()
    if err != nil {
        panic(err)
    }
    if d.Token == "" {
        panic("Auth Token Missing")
    }

    // --- Run the Tests ---
    flag.Parse()
    ex := m.Run()

    // --- Log off the test device ---
    d, err = d.Logoff()
    if err != nil {
        panic(err)
    }

    // --- End the Tests ---
    os.Exit(ex)
}

func TestGetUpdate(t *testing.T) {
    f, err := d.GetUpdate()
    if err != nil {
        t.Error(err)
    }
    fmt.Println(f)
}

The 'd' struct holds all the info I need to do the API call, and I was thinking that declaring it as a global, it would be available to all the test func's, but I always get "Auth Token Missing" errors when I call my API functions:

$ export THEIP="10.1.1.3"; go test -v
=== RUN   TestGetUpdate

--- FAIL: TestGetUpdate (0.00s)
    api_system_test.go:46: No Auth Token! You must Login() before calling other API calls
FAIL
exit status 1
FAIL    a10/axapi       0.015s

The test for the Auth Token passes in the TestMain(), but the updates to the struct don't seem to be coming out. I can't pass the struct as a var or a reference, as that breaks the testing. What am I doing wrong?

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
JD Allen
  • 799
  • 5
  • 12
  • Please come up with a minimal standalone example demonstrating your problem. – Volker Dec 01 '20 at 20:51
  • @Volker ?!? What's missing from this example? – JD Allen Dec 01 '20 at 21:27
  • 1
    It appears to expect the global `d` to be updated by `d.Login`, but you assign the result to a local variable. – JimB Dec 01 '20 at 23:05
  • @JimB Is not the 'var d Device' and the 'd, err := d.Login()' the same variable?!? I have this code working all over the place -- just not in the '_test.go' code. – JD Allen Dec 02 '20 at 00:46
  • 1
    No, `:=` declares new variables. – JimB Dec 02 '20 at 00:49
  • @JimB Oh? I was taught that it only was if the var didn't exist already. 'err' doesn't exist in this context, so you HAVE to use the ':=' in order to get it to work. 'd' already exists, so it isn't recreated. – JD Allen Dec 02 '20 at 00:58
  • You do not _HAVE_ to use `:=`, you can declare the variable outside the statement. It's not some arbitrary rule, it's simply about declaration vs assignment. Read https://golang.org/doc/effective_go.html#redeclaration and https://golang.org/ref/spec#Short_variable_declarations – JimB Dec 02 '20 at 14:12

1 Answers1

0

Once you start the testGetUpdate those values that you are looking for, as stated in TestMain, are not there for passing this test and the function call that it performs in the test. You would be better mocking the struct, placing a constant, or performing another setup for these values in another function that can be called and set those variables. The Constant may be the easiest especially if you are going to use this in other tests. Otherwise you are going to have to place the information in every test in order to pass the values of the structs.

Another option is to pass a t.run() inside of a main testing function that way the application knows what values you are wanting to run inside your tests.

Namor81
  • 42
  • 2