Does this compile for you? You’re returning a string from LoadQuery(), but not specifying a return parameter - this should fail with a “too many arguments to return” error at compile time.
In addition, if you do change LoadQuery() to return a string, the test would be redundant. But even if you did want to test if a variable was of a certain type (maybe LoadQuery return as interface{}, for example?), you wouldn’t test it like x != string. Rough example: https://play.golang.org/p/aGvCH8OkrWW
Correct, this didn’t compile until I added a return type of string.
Can you elaborate as to why the test would be redundant? Are tests not always necessary?
To write a test for this requirement, reading sql from a file into a string to be sent to the database query client… the problem I have is that my query itself that generates the report is thousands of lines long. This is an issue because thus far I have seen tests written that use back ticks select * from table for the successful test case.
Having said that maybe I can use a pattern matching expression so the test case would be,
got := LoadQuery()
want := `%select%from%`
if got != want {
t.Error("file not sql")
}
Thanks for your response, very grateful for any further input that will contribute to my understanding of testing in Go
This particular test would be redundant if you specify a return type of string and then test that the returned variable is of type string - the compiler will guarantee that the return type will always be string in this case. The application will not compile unless you’re returning a string in that function, so the test isn’t really testing anything. In your SQL query example, a more useful test might be that the result is not an empty string, for example (if you always expect to return a SQL query), or that the SQL query string returned is always a valid query for your purposes (similar to the second example you just posted I guess). I hope that makes sense, let me know if not and I can try to explain it another way
Adding my final solution. Further feedback is welcome but I am content that my question has been answered.
Firstly my code:
package main
import (
"fmt"
"io/ioutil"
"log"
)
var err error
func main() {
fmt.Println(LoadQuery())
}
// LoadQuery retrieves .sql file from filesystem
func LoadQuery() string {
// Load Query from file
content, err := ioutil.ReadFile("code_checker.sql")
if err != nil {
log.Fatal("File not found")
}
// Convert Query to String
query := string(content[:])
return query
}
When I remove the byte to string line and run the test I get this error.
c:\dev\go\src\###\reporter.go:53:2: cannot use content (type []byte) as type string in return argument
FAIL ### [build failed]
Error: Tests failed.
Otherwise with string conversion
2018/08/21 14:15:46 File not found
FAIL 0.200s
Error: Tests failed.
And my test:
package main
import (
"fmt"
"testing"
)
func TestLoadQuery(t *testing.T) {
t.Run("load sql from file", func(t *testing.T) {
// Test fails if either no file present or not string returned.
if len(LoadQuery()) > 0 {
fmt.Println("Empty String")
}
})
}
Ways this test could be improved I guess include… understanding how to mock a file for the test. Changing the test text to be more idiomatic, maybe the name for this test should be “load string from file” as this is what we are actually doing.