我有一个计划的任务,每天晚上汇总数据。每当我启动应用程序时,任务便会运行,而当我在应用程序上运行jUnit测试时,我想停止其运行。
@Scheduled(cron = "0 0 0 1 * ?")
public void SalesDataAggregation() {
//aggregation
}
修改
上面的方法也在这里被调用
@PostConstruct
public void init(){
SalesDataAggregation();
}
答案 0 :(得分:1)
由于 @PostConstruct 批注,方法 SalesDataAggregate 在启动时正在运行。如果要使其在测试期间不运行,则可以在测试文件夹中创建包含post构造的类,并添加 @primary 批注,以便它优先于主项目中的类。>
@Primary
public class ClassContainingPostConstruct{
}
答案 1 :(得分:0)
您可以将包含PostConstruct
的bean重新编写为EventListener
(https://spring.io/blog/2015/02/11/better-application-events-in-spring-framework-4-2)以便在启动时触发,我想这就是它的目的。然后可以将该bean绑定到某些Profile
上,以仅在特定启用的配置文件上触发。
另一种选择是使用属性有条件地触发它。
public class PostConstructBean {
public boolean isPostConstructEnabled;
public PostConstructBean(@Value("${postconstructenabled}" String value){
isPostConstructEnabled = Boolean.parseBoolean(value);
}
@PostConstruct
public void init(){
if(isPostConstructEnabled){
SalesDataAggregation();
}else{
//NOOP
}
}
}
然后将属性添加到您的环境属性/整体属性文件中。这增加了好处,使您可以更轻松地加载/禁用Bean
答案 2 :(得分:0)
在我的情况下,PostConstruct中的任何内容都不会使其他测试崩溃,只有Mockito.verify崩溃,因此我决定保留PostConstruct使用的注入的模拟类,然后在测试中重新模拟并重新注入它使用Mockito和ReflectionTestUtils。这避免了bean创建的问题,并允许我仅验证刚刚模拟的类:
被测类:
@Component
public class ClassUnderTest
{
@Autowired
private MockedClass nameOfActualBeanInClassUnderTest;
@PostConstruct
private void postConstructMethod()
{
Object param1 = new Object();
Object param2 = new Object();
this.nameOfActualBeanInClassUnderTest.mockedClassFunctionBeingHit(param1, param2);
}
}
测试类:
import static org.mockito.Mockito.*;
import org.springframework.test.util.ReflectionTestUtils;
public class Tests
{
// Class Under Test
@Autowired
private ClassUnderTest classUnderTest;
// Mocked Class
@MockBean
private MockedClass mockedClass;
@Test
public void actualTestThatAvoidsPostConstruct()
{
// ============== Ignore PostConstruct Errors ==============
// Note: You will probably want to capture the current mocked class
// to put it back in the class under test so that other tests won't fail
MockedClass savedMockedClass =
(MockedClass)ReflectionTestUtils.getField(this.classUnderTest,
"nameOfActualBeanInClassUnderTest");
this.mockedClass = mock(MockedClass.class);
ReflectionTestUtils.setField(this.classUnderTest,
"nameOfActualBeanInClassUnderTest",
this.mockedClass);
// ============== Setup Test ==============
Object response = new Object();
// Set return value when mockedClass' function is hit
// Note: Only need to pass params if your function actually has them
when(this.mockedClass.mockedClassFunctionBeingHit(param1, param2))
.thenReturn(response);
// ============== Test ==============
this.classUnderTest.testFunction();
// ============== Verify ==============
// Note: Only need to pass params if your function actually has them
verify(this.mockedClass).mockedClassFunctionBeingHit(param1, param2);
// ============== Reset Mocked Class ==============
ReflectionTestUtils.setField(this.classUnderTest,
"nameOfActualBeanInClassUnderTest",
savedMockedClass);
}
}