我主要在 GoogleMock 中使用有序期望,因此所有 EXPECT_CALL 都写在 testing::InSequence 对象的范围内。
现在我想放宽顺序,所以我将期望分为 2 个序列。你会说测试应该通过,但没有 - 它失败了,提示未满足的先决条件。我该如何推理?
编辑:我的代码的缩减版本:
//InSequence s; // uncomment this and it works
for (int i = 1; i <= 2; ++i)
{
{
//InSequence s; // uncomment this and it doesn't work
EXPECT_CALL(mock1, produceMessage(_))
.WillOnce(DoAll(SetArgReferee<0>(val1), Return(false)))
.WillOnce(DoAll(SetArgReferee<0>(val2), Return(false)))
.WillOnce(DoAll(SetArgReferee<0>(val2), Return(false)));
EXPECT_CALL(mock2, handleEvent(A<MyType>()));
EXPECT_CALL(mock2, handleMessage(NotNull()));
}
}
因此,如果 InSequence 嵌套在 for 循环内,我应该有部分顺序,与 InSequence 在外部的情况相比,这是一个宽松的要求。
我得到的错误:
Mock function called more times than expected - returning default value.
Function call: handleMessage(0xd7e708)
Returns: false
Expected: to be called once
Actual: called twice - over-saturated and active
然后,在测试结束时:
Actual function call count doesn't match EXPECT_CALL(mock2, handleMessage(NotNull()))...
Expected: to be called once
Actual: never called - unsatisfied and active
最佳答案
在 GoogleMock 学习曲线上取得更多进展后,我将尝试以一种足够通用且有用的方式回答我自己的问题。
让我们考虑以下完全有序期望的示例:
{
InSequence s;
EXPECT_CALL(mock1, methodA(_)); // expectation #1
EXPECT_CALL(mock2, methodX(_)); // expectation #2
EXPECT_CALL(mock1, methodA(_)); // expectation #3
EXPECT_CALL(mock2, methodY(_)); // expectation #4
}
现在,让我们将顺序一分为二。
{
InSequence s;
EXPECT_CALL(mock1, methodA(_)); // expectation #1
EXPECT_CALL(mock2, methodX(_)); // expectation #2
}
{
InSequence s;
EXPECT_CALL(mock1, methodA(_)); // expectation #3
EXPECT_CALL(mock2, methodY(_)); // expectation #4
}
目的是允许来自两个序列的期望“合并”,即以期望#1 作为#2 的前提条件和#3 作为#4 的前提条件,但不能超过此条件。
但是,下面的调用序列将满足完全有序的期望而不是“部分有序”的期望:
mock1.methodA(); // call #1
mock2.methodX(); // call #2
mock1.methodA(); // call #3
mock2.methodY(); // call #4
原因:完全有序的期望得到满足的原因很明显:示例只是按照编写的顺序满足了它们。作为 InSequence,他们一满意就退休。
但是,“部分排序”场景不起作用,因为调用 #1 将满足期望 #3,然后调用 #2 将匹配期望 #2,而期望 #2 无法满足,因为它以期望 #1 作为前提条件.尽管从技术上讲,期望 #1 和 #3 是相同的,但它们以相反的书写顺序得到满足,因为它们不属于相同的顺序,因此失败。
我觉得 Google Mock 没有很好地记录这种现象。我仍在寻找更好的形式化。我怀疑这里使用的“偏序”概念有问题。
关于c++ - 谷歌模拟 : why is a partial ordering of expectations harder to satisfy than a total ordering?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26160356/
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
假设我在Store的模型中有这个非常简单的方法:defgeocode_addressloc=Store.geocode(address)self.lat=loc.latself.lng=loc.lngend如果我想编写一些不受地理编码服务影响的测试脚本,这些脚本可能已关闭、有限制或取决于我的互联网连接,我该如何模拟地理编码服务?如果我可以将地理编码对象传递到该方法中,那将很容易,但我不知道在这种情况下该怎么做。谢谢!特里斯坦 最佳答案 使用内置模拟和stub的rspecs,你可以做这样的事情:setupdo@subject=MyCl
在ruby中,你可以这样做:classThingpublicdeff1puts"f1"endprivatedeff2puts"f2"endpublicdeff3puts"f3"endprivatedeff4puts"f4"endend现在f1和f3是公共(public)的,f2和f4是私有(private)的。内部发生了什么,允许您调用一个类方法,然后更改方法定义?我怎样才能实现相同的功能(表面上是创建我自己的java之类的注释)例如...classThingfundeff1puts"hey"endnotfundeff2puts"hey"endendfun和notfun将更改以下函数定
我有一个gem,它有一个根据Rails.env的不同行为的方法:defself.envifdefined?(Rails)Rails.envelsif...现在我想编写一个规范来测试这个代码路径。目前我是这样做的:Kernel.const_set(:Rails,nil)Rails.should_receive(:env).and_return('production')...没关系,只是感觉很丑。另一种方法是在spec_helper中声明:moduleRails;end而且效果也很好。但也许有更好的方法?理想情况下,这应该有效:rails=double('Rails')rails.sho
我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“
有没有办法让Ruby能够做这样的事情?classPlane@moved=0@x=0defx+=(v)#thisiserror@x+=v@moved+=1enddefto_s"moved#{@moved}times,currentxis#{@x}"endendplane=Plane.newplane.x+=5plane.x+=10putsplane.to_s#moved2times,currentxis15 最佳答案 您不能在Ruby中覆盖复合赋值运算符。任务在内部处理。您应该覆盖+,而不是+=。plane.a+=b与plane.a=
如何只加载map边界内的标记gmaps4rails?当然,在平移和/或缩放后加载新的。与此直接相关的是,如何获取map的当前边界和缩放级别? 最佳答案 我是这样做的,我只在用户完成平移或缩放后替换标记,如果您需要不同的行为,请使用不同的事件监听器:在你看来(index.html.erb):{"zoom"=>15,"auto_adjust"=>false,"detect_location"=>true,"center_on_user"=>true}},false,true)%>在View的底部添加:functiongmaps4rail