我想测试FooRepository.lock()
是否工作,在有人调用lock()
之后,其他人调用它应该等待。
以下是我最好的尝试,它不起作用。我相信原因是entityManger
和fooRepository
都参与了相同的交易。
如何从另一个事务调用lock()
?或者对悲观锁的单元测试有什么建议?谢谢!!
FooRepositoryTest:
package com.example.demo;
import java.util.UUID;
import javax.persistence.LockModeType;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@DataJpaTest
public class FooRepositoryTest {
@Autowired
private TestEntityManager entityManager;
@Autowired
private FooRepository fooRepository;
@Test
public void lockTest() {
// given
Foo foo = new Foo();
foo.setName("foo-name");
UUID fooId = fooRepository.save(foo).getFooId();
entityManager.flush();
entityManager.clear();
// when
Foo savedFoo = fooRepository.findOne(fooId);
fooRepository.lock(savedFoo);
// then
// I want something like this to be lock wait,
// something to confirm the above fooRepository.lock() work
entityManager.getEntityManager().lock(savedFoo, LockModeType.PESSIMISTIC_WRITE);
}
}
Foo类:
package com.example.demo;
import java.util.UUID;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Foo {
@Id
@GeneratedValue
private UUID fooId;
private String name;
public UUID getFooId() {
return fooId;
}
public void setFooId(UUID fooId) {
this.fooId = fooId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
FooApplication类:
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class FooApplication {
public static void main(String[] args) {
SpringApplication.run(FooApplication.class, args);
}
}
FooRepository类:
package com.example.demo;
import java.util.UUID;
import org.springframework.data.jpa.repository.JpaRepository;
public interface FooRepository extends JpaRepository<Foo, UUID>, FooRepositoryCustom {
}
FooRepositoryCustom类:
package com.example.demo;
public interface FooRepositoryCustom {
public void lock(Foo foo);
}
FooRepositoryImpl类:
package com.example.demo;
import javax.persistence.EntityManager;
import javax.persistence.LockModeType;
import org.springframework.beans.factory.annotation.Autowired;
public class FooRepositoryImpl implements FooRepositoryCustom {
@Autowired
private EntityManager entityManager;
@Override
public void lock(Foo foo) {
entityManager.lock(foo, LockModeType.PESSIMISTIC_WRITE);
}
}
发布于 2017-08-02 23:52:41
您的单元测试错了。
您可以使用而不是编写单元测试来执行由某个第三方框架实现的功能。单元测试是给你的单位的!
换句话说:您不需要验证锁定是否如预期的那样工作。你的单位:
entityManager.lock(foo, LockModeType.PESSIMISTIC_WRITE);
因此,您可以考虑在这里进行测试:确保使用预期参数调用实体管理器lock()
方法。
意思:验证您的代码是否使用了您认为应该使用的框架--但是不要测试其他人的代码!当你的单元测试显示框架错误时你会怎么做.你不能改变这一点!(当然,您可以编写bug报告)
免责声明:在特殊情况下,您可能假设某个第三方产品有错误--那么编写一个单元测试来测试这个假设可能非常有用。这样,您以后就可以对该产品的新版本运行单元测试,以查看bug是否仍然存在。
发布于 2020-09-29 12:28:46
使用集成测试测试悲观锁定处理很重要(我可以说是强制性的吗?)原因有二:
在博客文章用SpringBoot和JPA测试悲观锁处理中,您可以:
Spring框架仅用作示例。您可以轻松地为其他框架调整测试。
https://stackoverflow.com/questions/45477459
复制