Я думаю, вам будет очень трудно контролировать, какие ошибки и когда выдаются os.Stat
независимым от платформы способом из модульного теста.Если вам действительно нужен тест для пути, по которому возвращается неизвестный тип ошибки, лучшим вариантом может быть рефакторинг кода вашего пакета, чтобы вы могли смоделировать os.Stat
.Хотя вы не можете напрямую изменить поведение os.Stat
, воспользовавшись тем, что в Go есть первоклассные функции, вы можете использовать немного косвенности, чтобы высмеивать его с минимальными изменениями в вашем коде.Если код вашего пакета выглядит следующим образом:
package mypackage
import "os"
...
if _, err := os.Stat(path); err != nil {
if os.IsNotExist(err) {
continue
}
return errors.File().AddDetails(err)
}
...
Попробуйте изменить его рефакторинг для использования неэкспортированной переменной функции области пакета, которой назначено os.Stat
:
package mypackage
import "os"
var osStat = os.Stat
...
if _, err := osStat(path); err != nil {
if os.IsNotExist(err) {
continue
}
return errors.File().AddDetails(err)
}
...
Теперь, вВаш тестовый код (который должен быть в том же пакете, что и тестируемый код), вы можете переназначить osStat
на любую функцию с такой же сигнатурой, чтобы смоделировать ее:
package mypackage
import (
"os"
"testing"
)
func TestNotExistError(t *testing.T) {
osStat = func(string) (os.FileInfo, error) {
return nil, os.ErrNotExist
}
// in case other test functions depend on the unmocked behavior
defer func() {
osStat = os.Stat
}()
// rest of the test which triggers the codepath above
}
func TestOtherError(t *testing.T) {
osStat = func(string) (os.FileInfo, error) {
return nil, os.ErrInvalid
}
// in case other test functions depend on the unmocked behavior
defer func() {
osStat = os.Stat
}()
// rest of the test which triggers the codepath above
}
...