- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
出于测试目的,我想在 Go 中模拟随机数。所以我创建了随机界面。在单元测试期间,我返回标识函数,而为了实现,我使用 rand 包生成一个随机数。
这是在 Go 中模拟随机数的正确方法吗?任何帮助表示赞赏。
去 Playground :https://play.golang.org/p/bibNnmY2t1g
主要内容:
package main
import (
"time"
"math/rand"
"fmt"
)
func init() {
rand.Seed(time.Now().UnixNano())
}
type Random interface {
Uint(_ uint) uint
}
type rndGenerator func(n uint) uint
type Randomizer struct {
fn rndGenerator
}
func NewRandomizer(fn rndGenerator) *Randomizer {
return &Randomizer{fn: fn}
}
func (r *Randomizer) Uint(n uint) uint {
return r.fn(n)
}
func fakeRand(n uint) uint { return n }
func realRand(_ uint) uint { return uint(rand.Uint64()) }
func main() {
fakeRnd := NewRandomizer(fakeRand).Uint
fmt.Println(fakeRnd(1))
fmt.Println(fakeRnd(2))
realRnd := NewRandomizer(realRand).Uint
fmt.Println(realRnd(0))
fmt.Println(realRnd(0))
}
测试:
package main
import (
"testing"
"math/rand"
"reflect"
)
func TestNewRandomizer(t *testing.T) {
fn := func(n uint) uint { return n }
type args struct {
fn rndGenerator
}
tests := []struct {
name string
args args
want *Randomizer
}{
{
"test",
args{fn},
&Randomizer{fn},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := NewRandomizer(tt.args.fn); reflect.TypeOf(got) != reflect.TypeOf(tt.want) {
t.Errorf("NewRandomizer() = %v, want %v", got, tt.want)
}
})
}
}
func TestRandomer_Uint(t *testing.T) {
rnd := uint(rand.Uint64())
type fields struct {
fn rndGenerator
}
type args struct {
n uint
}
tests := []struct {
name string
fields fields
args args
want uint
}{
{
"test",
fields{func(n uint) uint { return n }},
args{rnd},
rnd,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
r := &Randomizer{
fn: tt.fields.fn,
}
if got := r.Uint(tt.args.n); got != tt.want {
t.Errorf("Randomizer.Uint() = %v, want %v", got, tt.want)
}
})
}
}
func Test_fakeRand(t *testing.T) {
rnd := uint(rand.Uint64())
type args struct {
n uint
}
tests := []struct {
name string
args args
want uint
}{
{
"test",
args{rnd},
rnd,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := fakeRand(tt.args.n); got != tt.want {
t.Errorf("fakeRand() = %v, want %v", got, tt.want)
}
})
}
}
func Test_realRand(t *testing.T) {
type args struct {
in0 uint
}
tests := []struct {
name string
args args
want bool
}{
{
"test",
args{0},
true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := realRand(tt.args.in0); got < 1 {
t.Errorf("realRand() = %v, want %v", got, tt.want)
}
})
}
}
最佳答案
您的示例没有真正使用 Random
接口(interface),因为模拟是在 Randomizer
类型的函数字段级别完成的。
如果可能的话,我建议放弃函数字段和函数,而是定义 Random
接口(interface)的两个单独实现。您可以为此使用空结构,它们起初可能看起来很奇怪,但它们具有占用 0 字节内存的良好特性。
推荐的主要原因是,当您使用函数字段时,您将失去将结构类型值与 reflect.DeepEqual
进行比较的能力。这是因为只有当它们具有相同的类型并且都是 nil 时,两个函数值才相等。
作为示例,让我们首先查看您的 TestNewRandomizer
,它是上述问题的一个症状。在测试中你只是比较返回值的类型,这是编译器已经确保的,所以测试是毫无意义的。
现在,假设您放弃了测试,因为它没有用,但出于某种原因您保留了函数字段。因此,任何依赖于 *Randomizer
的结构类型也将无法使用 DeepEqual
进行测试,并且在尝试对该类型进行测试时您将遇到同样的困难.
package main
import (
"time"
"math/rand"
"fmt"
)
func init() {
rand.Seed(time.Now().UnixNano())
}
type Random interface {
Uint(_ uint) uint
}
type Randomizer struct {}
func NewRandomizer() Randomizer {
return Randomizer{}
}
func (r Randomizer) Uint(n uint) uint {
return uint(rand.Uint64())
}
type FakeRandomizer struct {}
func NewFakeRandomizer() FakeRandomizer {
return FakeRandomizer{}
}
func (r FakeRandomizer) Uint(n uint) uint {
return n
}
func main() {
fakeRnd := NewFakeRandomizer().Uint
fmt.Println(fakeRnd(1))
fmt.Println(fakeRnd(2))
realRnd := NewRandomizer().Uint
fmt.Println(realRnd(0))
fmt.Println(realRnd(0))
}
请注意,我有意返回值而不是指针,因为空结构比指针小。
关于unit-testing - Go 中的模拟随机生成器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48360260/
我有以下功能: fun process(t: T, call: (U) -> Unit, map: (T) -> U) = call(map(t)) fun processEmpty(t: T,
关闭。这个问题需要更多focused .它目前不接受答案。 想改善这个问题吗?更新问题,使其仅关注一个问题 editing this post . 4年前关闭。 Improve this questi
我正在实现 SVG Tiny 1.1,但我无法理解“用户单元”的概念。 SVG 1.1 规范将每个没有指定单位(例如“mm”、“cm”、“pt”等)的 定义为“用户单位”。 在实现接口(interfa
我正在学习本教程 - http://blog.dasberg.nl/getting-your-frontend-code-quality-in-order/ - 将前端质量指标推送到 SonarQub
我用了 rails new app --skip-test-unit 因为最初,我认为我可以稍后添加测试。 我开发了我的应用程序的很大一部分。 现在,我想添加 Test::Unit 但我找不到任何有关
您如何对由某些报表引擎(例如Crystal Reports或SQL Server Reporting Services)创建的报表进行“单元测试”? 最佳答案 报告的问题类似于GUI的问题。 如果报表
今天在 Proggit 上,我正在阅读题为“Why Unit Testing Is A Waste of Time”的提交的评论线程。 我并不真正关心文章的前提,而是关心 comment对此作出: T
“单元测试”属于白盒测试还是黑盒测试?还是与其他两种测试完全不同? 最佳答案 我觉得这个article by Kent Beck更多地引用 TDD 和单元测试很好地总结了这一点。基本上,这取决于您实际
这是代码: def filterAcc(p: Tweet => Boolean, acc: TweetSet): TweetSet = { foreach(tweet => if(p(el
我打算编写一个抽象类来测试我所有的 DTO 和 DOMAIN 对象。此类将采用可模板对象(通用类型)并使用反射来获取其中的属性类型,并将一些默认值分配给标识的原始类型,稍后将通过访问它们来断言这些类型
我有一个像这样的简单容器特征: trait Handler { def apply[In, Out](in: In): Out } 当我尝试实现它时: new Handler { def ap
为什么这样编译 scala> import scala.concurrent.Future import scala.concurrent.Future scala> val f: Unit = Fu
您使用什么样的实践来使您的代码对单元测试更加友好? 最佳答案 TDD——首先编写测试,强制你要考虑可测试性和帮助编写实际的代码需要的,而不是你认为可能的需要 接口(interface)重构——使得 m
我在elasticsearch中有文本字段,我想在kibana上可视化词云... 第一步,我们需要标记它们,我使用了“标准标记器” ... 使用这种形式的词云可视化结果如下图所示: 但是我需要的是专有
我有以下方法: override def insertAll(notifications: Seq[PushNotificationEncoded]) (i
我的应用程序服务层中有很多方法正在做这样的事情: public void Execute(PlaceOrderOnHoldCommand command) { var order = _rep
一直在使用 Sails.js,但在为 Controller 设计 Jasmine 单元测试时遇到了麻烦。如果这很明显,请原谅我的无知,因为在过去的 3-4 个月里我才深入研究 JavaScript 开
Closed. This question does not meet Stack Overflow guidelines。它当前不接受答案。 想改善这个问题吗?更新问题,以便将其作为on-topic
在ReKotlin repo README中,有如下代码: data class CounterActionIncrease(val unit: Unit = Unit): Action 代码Unit
我想对一个业务类进行测试,但我遇到了这个问题:其中一个模拟对象与其他类(例如 Sites、URL 和 ComplexObject)有许多依赖关系。 我的问题是:如果我必须在需要测试的方法中使用我的模拟
我是一名优秀的程序员,十分优秀!