【发布时间】:2018-02-15 00:15:07
【问题描述】:
我正在多线程中测试一个事件处理器。所以我在我的测试用例中使用了 vmlens 的 concurrent-junit。 但是当我使用 ConcurrentTestRunner 而不是 SpringJunit4ClassRunner 自动装配 bean 时,我得到了空点异常。 这是我的pom
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.vmlens</groupId>
<artifactId>concurrent-junit</artifactId>
<version>1.0.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>2.6.0</version>
<scope>test</scope>
</dependency>
测试用例源码:
import com.anarsoft.vmlens.concurrent.junit.ConcurrentTestRunner;
import com.anarsoft.vmlens.concurrent.junit.ThreadCount;
@RunWith(ConcurrentTestRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class EventListenerTest {
@Autowired
private EventStore es; //defined in applicationContext.xml
@Autowired
private EntityAppender ea; //a @Component
......
@Test
@ThreadCount(10)
public final void testDefaultListener() {
Long bef = es.countStoredEvents();// nullpoint exception
TestEntity1 t1 = ea.appWithDefaultListener();// nullpoint exception
......
}
}
显然,bean 没有正确注入。 有没有什么办法解决这一问题?我应该扩展 AbstractJUnit4SpringContextTests 吗?
此处附上最新代码:
EventStore 是一个 Jpa 存储库:
public interface EventStore extends JpaRepository<DomainEvent, Long>{};
applicationContext.xml
<aop:config proxy-target-class="true" />
<context:annotation-config />
<jpa:repositories base-package="com.my"></jpa:repositories>
EntityAppender 只是为了测试而定义的。
@Component
public class EntityAppender {
@Autowired
private TestEntity1Repository myRepository; //another Jpa repository
public EntityAppender() {
super();
}
@Transactional
public TestEntity1 appWithDefaultListener() {
TestEntity1 t1 = new TestEntity1(UUID.randomUUID().toString().replaceAll("-", ""), "aaaaaaaaaaaa", 44,
LocalDate.now());
return myRepository.save(t1);
}
...
}
测试用例:
import com.anarsoft.vmlens.concurrent.junit.ConcurrentTestRunner;
import com.anarsoft.vmlens.concurrent.junit.ThreadCount;
@RunWith(ConcurrentTestRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class EventListenerTest {
@ClassRule
public static final SpringClassRule springClassRule = new SpringClassRule();
@Rule
public final SpringMethodRule springMethodRule = new SpringMethodRule();
@Autowired
private EventStore es;
@Autowired
private EntityAppender ea;
......
@Before
public void setUp() throws Exception {
bef = es.count(); //<====nullpoint exception due to es being null here
}
@Test
@ThreadCount(10)
public final void testDefaultListener() {
bef = es.count(); //<====== es worked well here
TestEntity1 t1 = ea.appWithDefaultListener();
......
}
}
【问题讨论】:
-
查看解决方案
@ClassRule和@Rule建议here,这样可以避免使用Spring的SpringJUnit4ClassRunner。 -
@SotiriosDelimanolis 我也找到了相同的解决方案here,谢谢。
-
@SotiriosDelimanolis 出现了另一个问题。当我在“@Before”方法中使用自动装配时,它给了我一个空点。 Spring 上下文似乎在“@Test”方法之前注入了组件。
-
你必须提供一个例子。
@Before方法应该在注入发生后调用。 -
很遗憾,我无法重现您所看到的行为。您能否在此处或在新问题中提供minimal reproducible example?
标签: java multithreading junit