我有一个测试实用程序,需要为每个测试方法提供一个新实例(以防止状态在测试之间泄漏)。到目前为止,我使用的是“原型”范围,但现在我希望能够将该实用程序连接到另一个测试实用程序中,并且每个测试的连接实例应该相同。
这似乎是一个标准问题,所以我想知道是否存在“测试方法”范围或类似的东西?
这是测试类和测试实用程序的结构:
@RunWith(SpringRunner.class)
@SpringBootTest
public class MyTest {
@Autowired
private TestDriver driver;
@Autowired
private TestStateProvider state;
// ... state
// ... methods
}
@Component
@Scope("prototype") // not right because MyTest and TestStateProvider get separate instances
public class TestDriver {
// ...
}
@Component
public class TestStateProvider {
@Autowired
private TestDriver driver;
// ...
}
我知道我可以使用@Scope("singleton")
和@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
,但这刷新了我所需的更多内容–每个测试一个新的TestDriver
实例就足够了。而且,这种方法容易出错,因为所有使用TestDriver
的测试都需要知道它们也需要@DirtiesContext
注释。所以我正在寻找更好的解决方案。
答案 0 :(得分:0)
前段时间我遇到了同样的问题,并提出了以下解决方案:
因此,使用以下方法和bean定义创建一个TestConfiguration类。
private MockSettings createResetAfterMockSettings() {
return MockReset.withSettings(MockReset.AFTER);
}
private <T> T mockClass(Class<T> classToMock) {
return mock(classToMock, createResetAfterMockSettings());
}
您的bean定义将如下所示:
@Bean
public TestDriver testDriver() {
return mockClass(TestDriver .class);
}
MockReset.AFTER
用于在运行测试方法后重置模拟。
最后将TestExecutionListeners
添加到您的Test类:
@TestExecutionListeners({ResetMocksTestExecutionListener.class})
答案 1 :(得分:0)
实现.react-autosuggest__container {
position: relative;
}
.react-autosuggest__input {
width: 240px;
height: 30px;
padding: 10px 20px;
font-family: Helvetica, sans-serif;
font-weight: 300;
font-size: 16px;
border: 1px solid #aaa;
border-radius: 4px;
}
.react-autosuggest__input:focus {
outline: none;
}
.react-autosuggest__container--open .react-autosuggest__input {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
.react-autosuggest__suggestions-container {
position: absolute;
top: 51px;
width: 280px;
margin: 0;
padding: 0;
list-style-type: none;
border: 1px solid #aaa;
background-color: #fff;
font-family: Helvetica, sans-serif;
font-weight: 300;
font-size: 16px;
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
z-index: 2;
}
.react-autosuggest__suggestion {
cursor: pointer;
padding: 10px 20px;
}
.react-autosuggest__suggestion--focused {
background-color: #ddd;
}
范围实际上很容易:
testMethod
只需注册测试执行侦听器,则所有public class TestMethodScope implements Scope {
public static final String NAME = "testMethod";
private Map<String, Object> scopedObjects = new HashMap<>();
private Map<String, Runnable> destructionCallbacks = new HashMap<>();
@Override
public Object get(String name, ObjectFactory<?> objectFactory) {
if (!scopedObjects.containsKey(name)) {
scopedObjects.put(name, objectFactory.getObject());
}
return scopedObjects.get(name);
}
@Override
public void registerDestructionCallback(String name, Runnable callback) {
destructionCallbacks.put(name, callback);
}
@Override
public Object remove(String name) {
throw new UnsupportedOperationException();
}
@Override
public String getConversationId() {
return null;
}
@Override
public Object resolveContextualObject(String key) {
return null;
}
public static class TestExecutionListener implements org.springframework.test.context.TestExecutionListener {
@Override
public void afterTestMethod(TestContext testContext) throws Exception {
ConfigurableApplicationContext applicationContext = (ConfigurableApplicationContext) testContext
.getApplicationContext();
TestMethodScope scope = (TestMethodScope) applicationContext.getBeanFactory().getRegisteredScope(NAME);
scope.destructionCallbacks.values().forEach(callback -> callback.run());
scope.destructionCallbacks.clear();
scope.scopedObjects.clear();
}
}
@Component
public static class ScopeRegistration implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory factory) throws BeansException {
factory.registerScope(NAME, new TestMethodScope());
}
}
}
批注类型的每个测试将有一个实例:
@Scope("testMethod")