我正在尝试对部分由 LaunchDarkly 标志控制的函数进行单元测试。我的愿望是对于除了一个之外的每个测试用例,将标志设置为
true
。
为了实现这一目标,我尝试在
false
测试用例的上下文中设置特定属性,然后可以通过 LaunchDarkly evaluator 进行评估,但我似乎找不到上下文键的正确设置,上下文类型以及使其工作的属性。
这是我所拥有的:
// Test file
import (
"github.com/launchdarkly/go-server-sdk/v7/ldcomponents"
"github.com/launchdarkly/go-server-sdk/v7/testhelpers/ldtestdata"
ld "github.com/launchdarkly/go-server-sdk/v7"
ofld "github.com/open-feature/go-sdk-contrib/providers/launchdarkly/pkg"
"github.com/open-feature/go-sdk/openfeature"
)
func NewTestFlaggingClient() (*ldtestdata.TestDataSource, *ld.LDClient) {
td := ldtestdata.DataSource()
var ldConfig ld.Config
ldConfig.ApplicationInfo.ApplicationID = "testing"
ldConfig.DataSource = td
ldConfig.Events = ldcomponents.NoEvents()
ldClient, err := ld.MakeCustomClient("fake-sdk-key", ldConfig, 5*time.Second)
if err != nil {
return nil, err
}
if err := openfeature.SetProvider(ofld.NewProvider(ldClient)); err != nil {
return nil, err
}
return td, ldClient
}
func Test_myMethod(t *testing.T) {
// ...
disabledCtx := openfeature.NewEvaluationContext("user",
map[string]interface{}{
"disable-flag": true
})
td, flagger := flags.NewTestFlaggingClient()
// Here I'm trying to create a flag that will always be true
// except when I see the context above
td.Update(td.Flag("method-enabled").
BooleanFlag().
VariationForKey("user", "disable-flag", false).
FallthroughVariation(true),
)
t.Run("Skip if flag is not set", func(t *testing.T) {
// add the disabledCtx to the parent context
ctx := openfeature.WithTransactionContext(ctx, disabledCtx)
err := myMethod(ctx)
// ...
})
}
// myMethod implementation
func myMethod(ctx context.Context) error {
// the Flag evaluation always receives this anonymous context, alongside the parent context
anonCtx := openfeature.NewEvaluationContext("anonymous", map[string]any{
"kind": "user",
"anonymous": true,
})
if !p.clients.Flags.Boolean(ctx, "mm-return-processor-enabled", false, anonCtx) {
return nil
}
}
我在任何地方都找不到有效的示例,我尝试调试
openfeature
和 laumchdarkly
包以查看发生了什么问题,但我还没有找到出路。
我不太确定你想在这里实现什么,但是
td.Update(td.Flag("method-enabled").
VariationForUser("user1", false).
FallthroughVariation(true),
)
您创建一个标志
method-enabled
,对于 false
为 user1
,为其他所有人创建 true
。 VariationForUser
是 VariationForKey("user", ...
的简写,这就是您正在使用的。我不确定您是否真的指的是用户 disable-flag
,我在这里选择 user1
。
假设您正在测试方法:
package main
import (
"context"
"github.com/open-feature/go-sdk/openfeature"
)
func MyMethod(ctx context.Context) (bool, error) {
of := openfeature.GetApiInstance()
client := of.GetClient()
val, err := client.BooleanValue(ctx, "method-enabled", false, openfeature.EvaluationContext{})
if err != nil {
return false, err
}
return val, nil
}
此测试将通过:
package main
import (
"context"
"testing"
"time"
ld "github.com/launchdarkly/go-server-sdk/v7"
"github.com/launchdarkly/go-server-sdk/v7/interfaces"
"github.com/launchdarkly/go-server-sdk/v7/ldcomponents"
"github.com/launchdarkly/go-server-sdk/v7/testhelpers/ldtestdata"
ofld "github.com/open-feature/go-sdk-contrib/providers/launchdarkly/pkg"
"github.com/open-feature/go-sdk/openfeature"
)
func NewTestFlaggingClient() (*ldtestdata.TestDataSource, error) {
td := ldtestdata.DataSource()
ldConfig := ld.Config{
ApplicationInfo: interfaces.ApplicationInfo{
ApplicationID: "testing",
},
DataSource: td,
Events: ldcomponents.NoEvents(),
}
ldClient, err := ld.MakeCustomClient("fake-sdk-key", ldConfig, 5*time.Second)
if err != nil {
return nil, err
}
if err := openfeature.SetProvider(ofld.NewProvider(ldClient)); err != nil {
return nil, err
}
return td, err
}
func TestMyMethod(t *testing.T) {
td, _ := NewTestFlaggingClient()
td.Update(td.Flag("method-enabled").
VariationForUser("user1", false).
FallthroughVariation(true),
)
enabledCtx := openfeature.NewEvaluationContext("user2", nil)
disabledCtx := openfeature.NewEvaluationContext("user1", nil)
ctx := context.Background()
type args struct {
ctx context.Context
}
tests := []struct {
name string
args args
want bool
wantErr bool
}{
{
name: "enabled",
args: args{openfeature.WithTransactionContext(ctx, enabledCtx)},
want: true,
},
{
name: "disabled",
args: args{openfeature.WithTransactionContext(ctx, disabledCtx)},
want: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := MyMethod(tt.args.ctx)
if (err != nil) != tt.wantErr {
t.Errorf("MyMethod() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("MyMethod() = %v, want %v", got, tt.want)
}
})
}
}
当你想使用属性时,使用:
...
import "github.com/launchdarkly/go-sdk-common/v3/ldvalue"
...
td.Update(td.Flag("method-enabled").
IfMatch("disable-flag", ldvalue.Bool(true)).ThenReturn(false).
FallthroughVariation(true),
)
enabledCtx := openfeature.NewEvaluationContext("user", nil)
disabledCtx := openfeature.NewEvaluationContext("user", map[string]interface{}{"disable-flag": true})
...