【发布时间】:2013-11-18 23:23:34
【问题描述】:
以下是我编写的第一批 RSpec 测试之一,在实施之后,我有几个问题悬而未决。
测试使用不同的输入运行相同的方法calculate,并验证生成的对象。然而,个别的小方法,如day_off? 没有明确测试。
我应该为各个方法编写测试而不是验证生成的对象吗?还是仅验证输出就足够了?还是应该同时测试各个方法和输出?
我认为典型的答案是“取决于”,但取决于什么?
我真的希望这不会作为一个主观问题而结束,因为我认为实际上可能会有一个有用的答案。
完整代码见:https://gist.github.com/asmand/d1ccbcd01789353c01c3
这是要测试的类:
class WeeklyFlexCalculator
attr_reader :params
def initialize(params)
@params = params
end
def calculate
group_efforts(
(params.start_date..params.end_date).map do |date|
daily_effort(date)
end.compact
)
end
def group_efforts(result)
weekly = result.group_by { |e| get_week_key(e[:date]) }
weekly.map do |key,w|
{
year: get_year_from_week_key(key),
week: get_week_from_week_key(key),
weekTarget: get_target_sum(w),
weekEffort: get_effort_sum(w),
efforts: w
}
end.sort { |a, b| b.efforts[0].date <=> a.efforts[0].date }
end
def daily_effort(date)
target = get_target(date)
effort = get_effort(date)
return if target == 0 && effort == 0
{
date: date,
effort: effort,
target: target,
diff: effort - target
}
end
def get_target_sum(efforts)
efforts.inject(0){|sum,e| sum + e[:target]}
end
def get_effort_sum(efforts)
efforts.inject(0){|sum,e| sum + e[:effort]}
end
def get_week_key(date)
date.cwyear.to_s + "|" + date.cweek.to_s
end
def get_year_from_week_key(key)
key.split('|')[0]
end
def get_week_from_week_key(key)
key.split('|')[1]
end
def get_target(date)
day_off?(date) ? 0 : params.user.hours_per_day
end
def get_effort(date)
ts = get_timesheet(date)
ts.nil? ? 0.0 : ts.TimeInHours
end
def day_off?(date)
date.wday == 0 or date.wday == 6 or params.holidays.include? date.to_s
end
def get_timesheet(date)
params.timesheets.select {|ts| ts.Date == date.to_s}.first
end
end
这是测试:
require './WeeklyFlexCalculator'
describe WeeklyFlexCalculator, "during Christmas week" do
subject(:calculation) { WeeklyFlexCalculator.new(params).calculate }
let(:params) do
messages = {
:start_date => Date.new(2013,12,23),
:end_date => Date.new(2013,12,29),
:holidays => ["2013-12-24", "2013-12-25", "2013-12-26"],
:timesheets => [],
:user => user
}
double(:params,messages)
end
let(:user) do
messages = {
:hours_per_day => 7.5
}
double(:user, messages)
end
let(:timesheet) do
messages = {
:Date => Date.new(2013,12,23).to_s,
:TimeInHours => 5.0
}
double(:timesheet, messages)
end
context "with no work performed" do
it { should have(1).item }
context "the week calculated" do
subject(:workweek) {calculation[0]}
its([:year]) { should eq "2013" }
its([:week]) { should eq "52" }
its([:weekTarget]) { should eq 15.0 }
its([:weekEffort]) { should eq 0.0 }
context "the work efforts" do
subject(:efforts) {workweek[:efforts]}
it { should have(2).items }
context "the first work effort" do
subject(:effort) {efforts[0]}
its([:target]) {should eq 7.5}
its([:diff]) {should eq -7.5}
its([:effort]) {should eq 0.0}
end
end
end
end
context "with work effort on normal day" do
before do
params.stub(:timesheets => [timesheet])
end
it { should have(1).item }
context "the week calculated" do
subject(:workweek) {calculation[0]}
its([:year]) { should eq "2013" }
its([:week]) { should eq "52" }
its([:weekTarget]) { should eq 15.0 }
its([:weekEffort]) { should eq 5.0 }
context "the work efforts" do
subject(:efforts) {workweek[:efforts]}
it { should have(2).items }
context "the first work effort" do
subject(:effort) {efforts[0]}
its ([:effort]) { should eq 5.0 }
its ([:diff]) { should eq -2.5 }
end
end
end
end
context "with work effort on a holiday" do
before do
timesheet.stub(:Date => Date.new(2013,12,24).to_s)
params.stub(:timesheets => [timesheet])
end
it { should have(1).item }
context "the week calculated" do
subject(:workweek) {calculation[0]}
its([:year]) { should eq "2013" }
its([:week]) { should eq "52" }
its([:weekTarget]) { should eq 15.0 }
its([:weekEffort]) { should eq 5.0 }
context "the work efforts" do
subject(:efforts) {workweek[:efforts]}
it { should have(3).items }
context "the first work effort" do
subject(:effort) {efforts[0]}
its ([:effort]) { should eq 0.0 }
its ([:diff]) { should eq -7.5 }
end
context "the second work effort" do
subject(:effort) {efforts[1]}
its ([:effort]) {should eq 5.0}
its ([:diff]) { should eq 5.0}
end
end
end
end
end
【问题讨论】: