How to write spring boot unit test for a method which calls another @Async method inside it?

huangapple go评论67阅读模式
英文:

How to write spring boot unit test for a method which calls another @Async method inside it?

问题

我需要为“processEvent”方法编写集成测试,该方法在其中调用了一个@Async方法。我尝试为该方法编写测试,但问题是它没有将Student对象保存到数据库。然而,删除@Async注解允许我保存对象。我想知道如何编写测试用例来消除@Async问题,同时在测试时保存学生对象。我已经附上了我的代码如下。

这是ClassA类,它包含我想要测试的方法。

@Service
public class ClassA {

    private final ConfigurationProcessor<Student> configurationProcessor;

    @Autowired
    public ClassA(ConfigurationProcessor<Student> configurationProcessor) {
        this.configurationProcessor = configurationProcessor;
    }

    public void processEvent(Configuration configuration) {
        configurationProcessor.process(configuration);
    }
}

这是ConfigurationProcessor接口类。

public interface ConfigurationProcessor<T> {
    void process(Configuration configuration);
}

这是它的实现类。

@Service
public class ConfigurationProcessoeStudents10Impl implements ConfigurationProcessor<Student> {
    private final StudentRepository studentRepository;

    @Autowired
    public ConfigurationProcessoeStudents10Impl(StudentRepository studentRepository) {
        this.studentRepository = studentRepository;
    }

    @Override
    @Async
    public void process(Configuration configuration) {
        studentRepository.save(Student.builder().Name(configuration.name).Age(configuration.age));
    }
}

这是我到目前为止编写的测试。

@EnableAutoConfiguration
@SpringBootTest
public class AudienceC10IT {

  @Autowired
  ClassA classA;
  
  @Test
  @Tag("VerifyProcess")
  @DisplayName("Verify kafka event consumer from configuration manager")
  void verifyProcess(){
    Configuration configuration = new Configuration("lal", 12);
    classA.processEvent(configuration);
  }
}

希望这些信息能帮助你编写测试用例并解决@Async的问题。

英文:

I need to write integration test for "processEvent" method which calls a @Async method inside it. I tried writing a test for this method, but the issue was it did not save the Student object to the DB. However removing @Async annotation allows me to save the object. I want to know how should I write Test cases for this method, eliminating the @Async issue. I want to save the student object while testing. I have attached my code and below.

Here is the ClassA and it has the method I want to test.

@Service
public class ClassA {

private final ConfigurationProcessor&lt;Student&gt; configurationProcessor;

	@Autowired
    public ClassA(ConfigurationProcessor&lt;Student&gt; configurationProcessor) {
        this.configurationProcessor = configurationProcessor;
	}

    public void processEvent(Configuration configuration) {
		configurationProcessor.process(configuration);
	}
} 

This is the interface ConfigurationProcessor class

public interface ConfigurationProcessor&lt;T&gt; {
    void process(Configuration configuration);
}

And this is its Impl class

@Service
public class ConfigurationProcessoeStudents10Impl implements ConfigurationProcessor&lt;Student&gt; {
    private final StudentRepository studentRepository;

    @Autowired
    public ConfigurationProcessoeStudents10Impl(StudentRepository studentRepository) {
        this.studentRepository = studentRepository;
		}
	
	@Override
    @Async
    public void process(Configuration configuration) {
		studentRepository.save(Student.builder().Name(configuration.name).Age(configuration.age));
	}
} 

This is the Test I have written so far.

@EnableAutoConfiguration
@SpringBootTest
public class AudienceC10IT {

  @Autowired
  ClassA classA;
  
  @Test
  @Tag(&quot;VerifyProcess&quot;)
  @DisplayName(&quot;Verify kafka event consumer from configuration manager&quot;)
  void verifyProcess(){
	Configuration configuration = new Configuration(&quot;lal&quot;,12);
	classA.processEvent(configuration);
  }
}

答案1

得分: 1

如果您已经设置了一个ThreadPoolTaskExecutor bean,您可以在测试中进行自动装配。
然后,在调用异步方法后,您可以等待其终止。
然后,您可以检查预期的行为/结果。

类似以下方式:

@Autowired
private ThreadPoolTaskExecutor asyncTaskExecutor;

@Test
void test() {
    callAsyncMethod();

    boolean terminated = asyncTaskExecutor.getThreadPoolExecutor().awaitTermination(1, TimeUnit.SECONDS);

    assertAsyncBehaviour();
}
英文:

If you have have set up a ThreadPoolTaskExecutor bean you can Autowire it in your test.
Then, after you call your async method, you can await the termination.
Then you can check for the expected behaviour / result.

Something like this:

@Autowired
private ThreadPoolTaskExecutor asyncTaskExecutor;

@Test
void test() {
    callAsyncMethod();

    boolean terminated = asyncTaskExecutor.getThreadPoolExecutor().awaitTermination(1, TimeUnit.SECONDS);

    assertAsyncBehaviour();


}

huangapple
  • 本文由 发表于 2023年2月8日 18:55:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/75384750.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定