我正在尝试在循环中测试代码,我将如何解决这个问题:
class MyClass
def initialize(topics, env, config, limit)
@client = Twitter::Streaming::Client.new(config)
@topics = topics
@env = env
@limit = limit
end
def start
@client.filter(track: @topics.join(",")) do |object|
# how would I test the code inside here, basically logical stuff
next if !object.is_a?(Twitter::Tweet)
txt = get_txt(object.text)
end
end
有办法做到这一点吗?
答案 0 :(得分:0)
如果您认为可以使用具有方法double
的{{1}} Twitter::Streaming::Client
,并且在调用此方法时会返回所需的输出:
filter
您需要手动构建let(:client) { double 'Twitter Client', filter: twitters }
对象(抱歉由于我缺乏上下文,但我从未使用过Twitter客户端),然后您可以对twitters
方法的结果进行断言。
答案 1 :(得分:0)
正如您所看到的,测试该代码非常棘手。这是因为依赖于Twitter客户端gem。
你可以走几条路:
不要测试它 - Twitter客户端gem应该为您提供Twitter::Tweet
个对象。您只测试您的逻辑,即get_txt
方法
做@Marcus Gomes所说的 - 创建一个实现filter
方法的集合双。
我更愿意做的是在规范中隐藏@client.filter
来电。
例如,在您的规范中:
some_collection_of_tweets = [
double(Twitter::Tweet, text: "I'll be back!"),
double(Twitter::Tweet, text: "I dare ya, I double dare ya!")
]
@my_class = MyClass.new(topics, env, config, limit)
allow(@my_class.client).to receive(:filter).and_return(some_collection_of_tweets)
这意味着每次课程调用some_collection_of_tweets
时都会返回@client.filter
集合,并且通过让您构建数据,您可以设置预期。
您需要更改的一件事是在课堂上设置attr_reader :client
。此类测试的唯一副作用是您将代码绑定到Twitter客户端的界面。
但就像其他一切......权衡:)
希望有所帮助!
答案 2 :(得分:0)
如果您真的想测试无限循环逻辑,也许你可以做这样的事情?
RSpec.describe MyClass do
subject { MyClass.new(['foo','bar'], 'test', 'config', 1) }
let(:streaming_client) { Twitter::Streaming::Client.new }
describe '#start' do
let(:valid_tweet) { Twitter::Tweet.new(id: 1) }
before do
allow(Twitter::Streaming::Client).to receive(:new)
.with('config').and_return(streaming_client)
end
after { subject.start }
it '#get_txt receives valid tweets only' do
allow(valid_tweet).to receive(:text)
.and_return('Valid Tweet')
allow(streaming_client).to receive(:filter)
.with(track: 'foo,bar')
.and_yield(valid_tweet)
expect(subject).to receive(:get_txt)
.with('Valid Tweet')
end
it '#get_txt does not receive invalid tweets' do
allow(streaming_client).to receive(:filter)
.with(track: 'foo,bar')
.and_yield('Invalid Tweet')
expect(subject).not_to receive(:get_txt)
end
end
end