Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cassandra/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unit testing 单元测试XDB查询的最简单方法应该是什么_Unit Testing_Go_Mocking - Fatal编程技术网

Unit testing 单元测试XDB查询的最简单方法应该是什么

Unit testing 单元测试XDB查询的最简单方法应该是什么,unit-testing,go,mocking,Unit Testing,Go,Mocking,我有一个只对XDB进行查询(读/写)的服务 我想对这个进行单元测试,但我不知道怎么做,我读过很多关于嘲笑的图图。很多公司都在处理类似这样的组件。但由于我正在使用XDB,所以无法使用它 我还发现我尝试过使用的其他组件过于复杂 我认为要做的是创建一个存储库层,这个接口应该实现我运行/测试所需的所有方法,并通过依赖项注入传递具体的类 我想这可能行得通,但这是最简单的方法吗 我想到处都有存储库,即使是对于小型服务,仅仅是为了让它们可以测试,似乎设计过度了 如果需要的话,我可以给你一些代码,但我认为我的问

我有一个只对XDB进行查询(读/写)的服务

我想对这个进行单元测试,但我不知道怎么做,我读过很多关于嘲笑的图图。很多公司都在处理类似这样的组件。但由于我正在使用XDB,所以无法使用它

我还发现我尝试过使用的其他组件过于复杂

我认为要做的是创建一个存储库层,这个接口应该实现我运行/测试所需的所有方法,并通过依赖项注入传递具体的类

我想这可能行得通,但这是最简单的方法吗

我想到处都有存储库,即使是对于小型服务,仅仅是为了让它们可以测试,似乎设计过度了


如果需要的话,我可以给你一些代码,但我认为我的问题更多的是理论性的,而不是实践性的。这是模拟自定义DB进行单元测试的最简单方法。

根据其定义,如果您使用外部资源测试集成,我们谈论的是集成测试,而不是单元测试。所以我们有两个问题要解决

单元测试 您通常要做的是有一个数据访问层,它接受接口,而接口又很容易模拟,您可以对应用程序逻辑进行单元测试

package main

import (
    "errors"
    "fmt"
)

var (
    values   = map[string]string{"foo": "bar", "bar": "baz"}
    Expected = errors.New("Expected error")
)

type Getter interface {
    Get(name string) (string, error)
}

// ErrorGetter implements Getter and always returns an error to test the error handling code of the caller.
// ofc, you could (and prolly should) use some mocking here in order to be able to test various other cases
type ErrorGetter struct{}

func (e ErrorGetter) Get(name string) (string, error) {
    return "", Expected
}

// MapGetter implements Getter and uses a map as its datasource.
// Here you can see that you actually get an advantage: you decouple your logic from the data source,
// making refactoring (and debugging) **much** easier WTSHTF.
type MapGetter struct {
    data map[string]string
}

func (m MapGetter) Get(name string) (string, error) {
    if v, ok := m.data[name]; ok {
        return v, nil
    }

    return "", fmt.Errorf("No value found for %s", name)
}

type retriever struct {
    g Getter
}

func (r retriever) retrieve(name string) (string, error) {
    return r.g.Get(name)

}

func main() {
    // Assume this is test code. No tests possible on playground ;)
    bad := retriever{g: ErrorGetter{}}
    s, err := bad.retrieve("baz")
    if s != "" || err == nil {
        panic("Something went seriously wrong")
    }

    // Needs to fail as well, as "baz" is not in values
    good := retriever{g: MapGetter{values}}
    s, err = good.retrieve("baz")
    if s != "" || err == nil {
        panic("Something went seriously wrong")
    }

    s, err = good.retrieve("foo")

    if s != "bar" || err != nil {
        panic("Something went seriously wrong")
    }
}
在上面的例子中,我实际上必须实现两个getter来覆盖所有的测试用例,因为我不能使用模拟库,但您可以理解

至于过度工程:简单明了,不,这不是过度工程。这就是我个人所说的正当工艺。从长远来看,适应它是值得的。也许不是在这个项目中,而是在未来的一个项目中

集成测试 狡猾的。我倾向于在提交查询之前确保查询是正确的;)


在极少数情况下,我真的想在CI中验证我的查询,例如,我通常创建一个Makefile,然后生成一个docker(-compose),它提供我想要集成的内容,然后运行测试。

要扩展@Markus W Mahlberg answer:

如果目标是验证查询是否有效并实际针对流入执行,则没有针对流入执行这些查询的快捷方式。这些通常被认为是“集成”测试。我发现使用docker compose,这些测试可以与单元测试一样可靠,并且速度足够快,可以集成到CI中。在CI中执行测试使本地工程师能够轻松地运行这些测试,以验证其查询更改

我想,到处都有存储库,即使是针对小型服务,只是为了让它们可以测试,这似乎是过度设计了。

我发现这是一个相当两极分化的讨论。并为支持轻松隔离和执行代码的特定组件铺平了道路


我想对此进行单元测试,但不确定如何进行,

我认为这是非常微妙的,IMO单元测试查询提供了负值。价值来自使用存储库接口,允许您的单元测试显式地配置您将从inflow接收的响应,以便充分使用您的应用程序代码。这不提供有关流入的反馈,这就是为什么集成测试对于验证应用程序是否可以有效地配置、连接和查询流入非常重要。此验证在部署应用程序时隐式发生,此时,就反馈而言,它比在本地和使用集成测试的CI中进行验证要昂贵得多


我创建了一个图表,试图说明这些差异:


使用repository进行的单元测试主要集中在您的应用程序代码上,对于与流入有关的任何事情都没有提供多少反馈/价值。集成测试对于验证您的客户机很有用(可能会扩展到您的应用程序,具体取决于测试执行的位置,但我更喜欢将其绑定到客户机,因为您已经获得了来自接口和调用的静态反馈)。最后,正如@Markus指出的,从集成测试到e2e测试的步骤非常小,并且允许您进行测试

我会选择界面。我不认为它们设计过度,因为它们为代码库添加了一个很好的抽象级别。IMO这一点也不过分:)我认为,在这里,我甚至会说,实际上集成测试应该针对从生产中克隆的登台环境进行。到那时,端到端测试只是一个小步骤,“仅”进行集成测试的目的和有效性变得相当可疑。好吧,对于synthetise来说,模拟DB进行单元测试并不会给我的测试带来太大的价值,所以我不必麻烦,相反,我应该进行集成测试,但你认为添加存储库层会增加价值,即使在小项目中,也应该进行编码,即使不需要模拟。这是正确的吗?