Cim*_*imm 5 ruby setter attributes rspec
我正在使用Sinatra(1.2)和RSpec(2.5),并且想要创建一个具有属性TDD样式的新对象.这是最终结果的样子:
class User
def initialize(name)
@name = name
end
end
Run Code Online (Sandbox Code Playgroud)
我知道我必须在实现之前编写示例,但我想在这里解释我的问题.:)这是我到目前为止没有工作的规范:
describe User
it "creates a new user object" do
name = mock("A name")
user = mock(User) # shouldn't do this, see the reply's
user.should_receive(:name=).with(name)
User.new(name)
end
end
Run Code Online (Sandbox Code Playgroud)
当我运行RSpec时,我得到"预期:1次,收到0次"错误.知道如何解释RSpec我想分配名称属性吗?
注意:我没有使用Rails,没有使用ActiveRecord或任何东西,只有Ruby.
The*_*heo 12
首先,让我解释为什么你写的规范不起作用:
您设置期望返回的模拟对象mock(User)
应该接收name=
.这有两个问题.首先,模拟将不会收到任何东西,因为它永远不会被调用.mock(User)
返回一个模拟对象,它不能用于设置User
类对象将接收的期望(这样做User.should_receive(...)
).其次,即使您已经在User
类对象上设置了期望,该对象也永远不会收到name=
.这也有两个原因:首先是因为name=
(如果它存在)将是一个实例方法,因此没有在类对象上调用,其次,你声明没有name=
实例方法.你的代码所做的是它设置一个实例变量.
现在,你应该怎么写这个测试?你不应该.测试是定义和断言行为,而不是实现.设置实例变量是纯实现.在您的示例代码中没有办法@name
从类外部获取实例变量的值,因此没有理由为它编写测试.
显然你的代码只是一个例子,任何有用的东西都会对@name
变量做些什么,这就是你应该测试的东西.首先编写一个测试User
对象将用于什么,然后编写完成该测试所需的所有实现(但不多).编写一个测试,反映对象在实际生产代码中的使用方式.
我真的建议你不要使用模拟来解决这个问题.这不是他们想要的.事实上,指定这样的getter/setter并不是TDD的真正含义.我们的想法是让一个要求驱动设置者/吸气剂存在.例如,可能要求用户的姓名在他/她登录时出现在欢迎消息中.然后您可能会执行以下操作:
describe 'login process' do
it "displays user's name after successful login" do
user = User.new("Cimm", "cimm@somewhere.com", "secret")
post "/login", :email => "cimm@somewhere.com", :password => "secret"
last_response.body.should =~ /Welcome Cimm/m
end
end
Run Code Online (Sandbox Code Playgroud)
这指定了行为,并强制您实现设置name属性的方法(通过构造函数,在本例中)和访问它的方法.无需直接指定构造函数.
归档时间: |
|
查看次数: |
8672 次 |
最近记录: |