2016-06-02 1 views
1

Как бы вы написали тест для функции, которая возвращает значение, которое может быть либо нулевым, либо конкретным значением? Меня не волнует сама фактическая ценность, мне просто интересно, вернётся ли значение или нет.Тестирование существования на возвращаемое значение, которое может быть конкретным или нулевым

type CustomType struct{} 

func TestSomeFunc(t *testing.T) { 
    case := map[string]struct { 
    Input string 
    Expected *CustomType // expected result 
    Error error // expected error value 
    } { 
    "test case 1": 
     "input", 
     &CustomType{}, // could be nil or a concrete value  
     nil, 
    "test case 2": 
     "input", 
     nil, // could be nil or a concrete value  
     ErrSomeError, 
    } 

    actual, err := SomeFunc(case.Input) 
    if (actual != case.Expected) { 
    t.Fatalf(...) 
    } 
} 

и функция для тестирования может выглядеть примерно так:

func SomeFunc(input string) (*CustomType, error) { 
    foo, err := doSomething() 
    if err != nil { 
    return nil, err 
    } 
    return foo, nil 
} 

Я предполагаю, что логика, я хочу это:

if ((case.Expected != nil && actual == nil) || 
    (case.Expected == nil && actual != nil)) { 
    t.Fatalf(...) 
} 

Есть ли лучший способ просто утверждать существования вместо сравнения конкретных типов?

+0

Почему вы не можете использовать 'if (case.Expected! = Actual)'? В качестве комментария, поскольку мне может не хватать точки. – abligh

+0

@abligh, которые не будут работать, если они не равны, и ни один из них не равен – BenjaminRH

+1

Условием или оператором, который вы хотите, является [XOR] (https://en.wikipedia.org/wiki/Exclusive_or) (или его отрицание) , который не существует в Go для операндов типа 'bool'. Для получения дополнительной информации/обходной путь, проверьте: [Нет ли оператора XOR для булевых языков в golang?] (Http://stackoverflow.com/questions/23025694/is-there-no-xor-operator-for-booleans-in-golang) – icza

ответ

2

Это не намного короче, чем у вас, но я думаю, что вы хотите, чтобы тест пройти только тогда, когда (case.Expected == nil) == (actual == nil), сравнивая результаты двух сравнений (true или false) против nil. Here's a short program demonstrating:

package main 

import (
    "fmt" 
) 

func main() { 
    isNil, isNotNil, otherNotNil := []byte(nil), []byte{0}, []byte{1} 
    fmt.Println("two different non-nil values\t", (otherNotNil == nil) == (isNotNil == nil)) 
    fmt.Println("a nil and a non-nil value\t", (isNil == nil) == (isNotNil == nil)) 
    fmt.Println("two nil values\t\t\t", (isNil == nil) == (isNil == nil)) 
} 

Как пользователь icza указывает, вы можете изменить внешний == в != (что дает вам что-то вроде (actual == nil) != (expected == nil)), чтобы получить true, когда есть несоответствие , а не когда есть совпадение.

+0

спасибо за ответ, но я думаю, что сценарий '(isNotNil == nil) == (isNotNil == nil)' все равно вызовет провал теста, хотя он должен пройти, поскольку и фактическое значение, и ожидаемое значение не являются ноль. – user34234

+2

@ user34234 Это будет работать, потому что если оба они не являются '' nil', то выражение оценивается как '(false) == (false)', которое является 'true'. Это выражение в основном фиксируется, когда тест должен быть успешным. Если вы хотите, чтобы условие завершилось с ошибкой, используйте '! =' В середине: '(case.Expected == nil)! = (Actual == nil)' – icza

+0

@icza прав, и я добавил к демонстрационной программе показать, что случай, о котором вы говорите, работает. – twotwotwo

Смежные вопросы