我有一个drools规则文件,它使用规则中的服务类.所以一条规则做了这样的事情:
eval(countryService.getCountryById(1)!= null)
在使用@service和@Transactional(propagation = Propagation.SUPPORTS)注释的验证服务中,drools文件用于statelessKnowledgebase,并添加应在流氓中使用的事实.完成后,调用session.execute(fact)并启动规则引擎.
为了测试规则,我想将countryService.getCountryById()存根.使用mockito没什么大问题.对于使用drools设置的其他服务也做了这个,它工作正常.然而,在这种特殊情况下,countryService没有存根,我无法弄清楚原因.花了很多时间并检查我的代码后,我发现在服务之上使用@Transactional或缺少这个注释会产生差异.缺少@Transaction使mockito模拟了countryservice没有任何问题,让@transactional到位导致mockito失败(没有任何错误或提示)注入模拟以便使用原始的countryservice对象.
我的问题是为什么这个注释会导致这个问题.为什么在设置@Transactional时无法模拟注入模拟?我注意到mockito失败了,因为我在调试和检查countryService时将它作为全局添加到drools会话中当我在debugwindow中检查countryservice时,我看到以下区别:
与@transactional:countryService的值为CountryService $$ EnhancerByCGLIB $$ b80dbb7b
没有@transactional:countryService的值为CountryService $$ EnhancerByMockitoWithCGLIB $$ 27f34dc1
除了@transactional之外,我在乡村服务方法中发现断点getCountryById并且调试器在该断点处停止,但是没有@transactional我的断点被跳过,因为mockito会绕过它.
ValidationService:
@Service
@Transactional(propagation=Propagation.SUPPORTS)
public class ValidationService
{
@Autowired
private CountryService countryService;
public void validateFields(Collection<Object> facts)
{
KnowledgeBase knowledgeBase = (KnowledgeBase)AppContext.getApplicationContext().getBean(knowledgeBaseName);
StatelessKnowledgeSession session = knowledgeBase.newStatelessKnowledgeSession();
session.setGlobal("countryService", countryService);
session.execute(facts);
}
Run Code Online (Sandbox Code Playgroud)
和测试类:
public class TestForeignAddressPostalCode extends BaseTestDomainIntegration
{
private final Collection<Object> postalCodeMinLength0 = new ArrayList<Object>();
@Mock
protected CountryService countryService;
@InjectMocks
private ValidationService level2ValidationService;
@BeforeMethod(alwaysRun=true)
protected void setup()
{
// Get the object under test …Run Code Online (Sandbox Code Playgroud)