如何管理测试的依赖项初始化代码

huangapple go评论73阅读模式
英文:

How to manage initialisation code of dependencies for tests

问题

我有一个日志包装器(在底层使用logrus实现),我正在使用这个包在我的应用程序中进行日志记录。我通过依赖注入将日志记录器变量传递给每个需要的包。

在这里,当为每个包编写测试用例时,我必须编写一些代码来初始化日志记录器包。有没有办法避免为每个使用日志记录器的包编写单独的初始化代码?

logger/log.go

type Logger interface {
	Info(args ...interface{})
	Infof(format string, keyvals ...any)
	InfoWithFields(fields map[string]interface{}, msg ...interface{})

	Debug(args ...interface{})
	Debugf(format string, keyvals ...any)
	DebugWithFields(fields map[string]interface{}, msg ...interface{})
}

app_test.go

func setupLogrusLogger() (*bytes.Buffer, Logger) {
	buf := &bytes.Buffer{}
	logrusLogger := log.New()
	logrusLogger.Out = buf
	logrusLogger.Formatter = &log.JSONFormatter{}
	return buf, NewLogrusLogger(logrusLogger)
}

func TestSomething(t *testing.T) {
  // 如果需要,可以使用buf来检查记录的内容
  buf, logger := setupLogrusLogger()
  Something(logger)
}

在这里,对于每个使用日志记录器的包,我都需要定义类似于setupLogrusLogger的初始化函数。有没有办法避免为我编写测试用例的每个包单独编写这个函数?

英文:

I have a log wrapper (uses logrus implementation underneath) and I’m using this package to log across my app. The way I do this is by passing the logger variable to each of the required packages through dependency injection.

Here, when writing test cases for each of the packages, I have to write some code to initialise the logger package. How do we avoid having to write initialisation code for the test cases of every package which uses the logger?

logger/log.go

type Logger interface {
	Info(args ...interface{})
	Infof(format string, keyvals ...any)
	InfoWithFields(fields map[string]interface{}, msg ...interface{})

	Debug(args ...interface{})
	Debugf(format string, keyvals ...any)
	DebugWithFields(fields map[string]interface{}, msg ...interface{})
}

app_test.go

func setupLogrusLogger() (*bytes.Buffer, Logger) {
	buf := &bytes.Buffer{}
	logrusLogger := log.New()
	logrusLogger.Out = buf
	logrusLogger.Formatter = &log.JSONFormatter{}
	return buf, NewLogrusLogger(logrusLogger)
}

func TestSomething(t *testing.T) {
  // buf can be used to inspect what gets logged if required
  buf, logger := setupLogrusLogger()
  Something(logger)
}

Here, for each of the packages which uses logger, I'd have to initialise the logger by defining something similar to setupLogrusLogger. Is there any way to avoid having to write this separately for each package I'm writing tests for?

答案1

得分: 1

导出依赖初始化函数,并在非_test.go文件中声明它,以便其他包可以导入并重用它。如果您想将测试逻辑与包的正常代码分离,可以将初始化函数移动到一个提供测试工具的包中。

只要您仅从_test.go文件中导入此类测试工具包(而不是从普通文件中导入),测试工具代码就不会包含在实际程序的编译二进制文件中。


这种测试工具包的示例可以在标准库中找到:

net/http/httptest

> httptest包提供了用于HTTP测试的实用工具。

net/internal/socktest

> socktest包提供了用于套接字测试的实用工具。

os/exec/internal/fdtest

> fdtest包提供了用于在exec过程中处理文件描述符的测试辅助函数。

testing/quick

> quick包实现了用于黑盒测试的实用函数。

testing/fstest

> fstest包实现了对文件系统实现和用户进行测试的支持。

testing/iotest

> iotest包实现了主要用于测试的读取器和写入器。

英文:

Export the dependency initializing function and declare it in a non-_test.go file so that the other packages can import and reuse it. If you'd like to separate the test logic from the package's normal code you can move the initializing function to a package that provides utilities for testing.

And, as long as you import such test-utility packages only from within _test.go files (and not from normal files), the test utility code won't make it into the actual program's compiled binary.


Examples of such test-utility packages can be found in the standard library:

net/http/httptest

> Package httptest provides utilities for HTTP testing.

net/internal/socktest

> Package socktest provides utilities for socket testing.

os/exec/internal/fdtest

> Package fdtest provides test helpers for working with file descriptors across exec.

testing/quick

> Package quick implements utility functions to help with black box testing.

testing/fstest

> Package fstest implements support for testing implementations and users of file systems.

testing/iotest

> Package iotest implements Readers and Writers useful mainly for testing.

huangapple
  • 本文由 发表于 2023年5月29日 20:49:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/76357533.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定