使用活动记录悲观锁定时,rspec更改期望失败

时间:2015-07-27 18:38:03

标签: ruby-on-rails rspec pessimistic-locking

我有一个Rails 4.2.0方法,它使用悲观锁定来更改计数器

class Foo < < ActiveRecord::Base
  def bump!
    transaction do
      lock!
      parent.lock!

      lock.counter += 1
      parent.counter += 1

      save!
      parent.save!
    end
  end
end

我正在使用Rspec 3.1进行测试

expect{foo.bump!}.to change(foo, :counter).by(1)
expect{foo.bump!}.to change(foo.parent, :counter).by(1)

第一个change(foo, :counter)测试通过但第二个change(foo.parent, :counter)失败,除非我同时注释lock!parent.lock!

如果我像这样重写失败的测试,它会通过

prev_counter = foo.parent.counter
foo.bump!
expect(foo.parent.counter).to eq prev_counter + 1

为什么它不适用于expect{...}.to change

1 个答案:

答案 0 :(得分:1)

您的问题是,您的RSpec测试中foo.parent的实例与parent方法正在修改的Foo#bump!的实例不同,因为调用parent.lock! {{ 3}}因此您修改了与reloads the parent association to get the lock不同的实例。最简单的解决方法是使用change { }语法,该语法不会将接收者实例绑定到foo.parent,而只是foo,而不是expect{foo.bump!}.to change{foo.counter}.by(1) expect{foo.bump!}.to change{foo.parent.counter}.by(1) ,它不会发生变化,如下所示:

<?php
define('HOST','X');
define('USER','X');
define('PASS','X');
define('DB','X');

$con = mysqli_connect(HOST,USER,PASS,DB);

$name = $_POST['name'];
$pass = $_POST['pass'];

$query = "SELECT * from tbl_user where username = '$name'";
$result = mysqli_query($con, $query);
$n = mysqli_num_rows($result);
if($n>0){
  $data = array(
        'status'    => 0,
        'message' => 'Username already exists'
  );
}else{
  $sql = "insert into tbl_user (username,password) values ('$name','$pass')";
  if(mysqli_query($con,$sql)){
    $data = array(
        'status'    => 1,
        'message' => 'Successfull'
  );
  }else{
    $data = array(
        'status'    => 2,
        'message' => 'Failed'
  );
  }
}
mysqli_close($con);
echo json_encode($data);
?>

此修复程序适用于我。