我正在 RSpec 中编写请求测试,在我正在测试的控制器路径过程中,应用程序发出两个 Turbo 流广播。
我无法在这种情况下达到
broadcast_to
的期望。我觉得我已经很接近了,但我碰壁了,我想在继续研究的同时问一个问题。
问题模特是新闻稿,其中有很多新闻稿图片模特。每个新闻稿图片模型都附有一张图片。
控制器操作获取文件附件并将其附加到新闻稿模型,然后广播针对框架的更新:
image_model.broadcast_replace_to(image_model.press_release, target: "slot_#{image_model.position}"
我们这样做
image_model.press_release
来传入 *streamable
的原因是因为我们的视图通过 turbo_stream_from(@press_release)
启动 Turbo 流,所以我们需要定位正确的流。
我有这样的期望,但它只是不正确:
expect do
post press_release_images_path(press_release), params: params,
headers: { 'Content-Type' => 'multipart/form-data' }
end.to broadcast_to(press_release).from_channel(Turbo::StreamsChannel)
此代码片段似乎至少让测试运行,但它失败了,因为该频道的广播数为 0。但奇怪的是,在运行此测试时,在我的测试日志中,我看到了类似的流名称。
来自上面期望块的失败消息:
expected to broadcast exactly 1 messages to turbo:streams:Z2lkOi8vcHJlc3MtcmVsZWFzZS1nZW5lcmF0b3IvUHJlc3NSZWxlYXNlLzE5NDM, but broadcast 0
测试控制器操作日志:
Rendered press_releases/images/_display.html.erb (Duration: 15.2ms | Allocations: 9700) [ActionCable] Broadcasting to Z2lkOi8vcHJlc3MtcmVsZWFzZS1nZW5lcmF0b3IvUHJlc3NSZWxlYXNlLzE5NDM: "<turbo-stream action=\"update\"...
还有第二次广播,但同样的问题仍然存在:我似乎总体方向是正确的,但似乎无法弄清楚如何匹配流名称。生成的字符串同时出现在 RSpec 错误消息和测试日志中,但我不确定如何协调它们以使测试通过。
虽然我热衷于按照我在这里概述的相同形状解决问题,但我愿意接受测试此行为的替代方法!
我最终选择了模拟路线,尽管它没有达到目标。我们基本上只是设置了一个期望,即在
image_model
实例上调用广播方法。
这并不是真正的副作用测试,但它达到了测试的目的:
expect_any_instance_of(PressReleaseImage).to receive(:broadcast_replace_to).once
expect_any_instance_of(PressReleaseImage).to receive(:broadcast_update_to).once
expect do
post press_release_images_path(press_release), params: params, headers: { 'Content-Type' => 'multipart/form-data' }
end.to change { press_release.reload.images.size }.from(0).to(1)
鉴于 Turbo 是经过良好测试的库代码,检查方法是否已发送可以让我充分保证事情会正常进行。