![](/img/trans.png)
[英]jmockit verifications block throwing Missing 1 invocation to methodName
[英]jmockit expectation keeps throwing missing invocation even though I'm calling it
我正在創建一個 Spring 應用程序,以下是相關的 controller、存儲庫、測試和錯誤消息。
我的應用程序在功能方面沒有任何問題,但它沒有通過這個單元測試。
我主要是 jmockit 測試單元中的 Expectations 方法有問題。 我看不出為什么一直說我錯過了一個調用? 盡管我確實在我的 controller 的最后一個 else 塊中給他們打電話
skillRepository.findAllById((List<Integer>))
job.setSkills((List<Skill>))
我一直在這里梳理其他人的類似問題,但無法解決我的問題。 先感謝您。
Controller
@PostMapping("add")
public String processAddJobForm(@ModelAttribute @Valid Job newJob,
Errors errors, Model model, @RequestParam int employerId,
@RequestParam List<Integer> skills) {
if(errors.hasErrors() || skills.size()==1){
if(skills.size()==1){
model.addAttribute("skills_error","You have to choose at least one skill");
}
model.addAttribute("title","Add Job");
model.addAttribute("employers",employerRepository.findAll());
model.addAttribute("skills",skillRepository.findAll());
return "add";
}
Optional<Employer> result = employerRepository.findById(employerId);
if(result.isEmpty()){
model.addAttribute("title","Invalid Employer ID: "+employerId);
return "add";
}else{
Employer employer = result.get();
newJob.setEmployer(employer);
List<Skill> skillObjs = (List<Skill>) skillRepository.findAllById(skills);
newJob.setSkills(skillObjs);
jobRepository.save(newJob);
return "redirect:";
}
}
存儲庫
@Repository
public interface SkillRepository extends CrudRepository<Skill,Integer> {
}
測試單元
/*
* Verifies that HomeController.processAddJobForm queries skillRepository and sets skills properly
* */
@Test
public void testProcessAddJobFormHandlesSkillsProperly (
@Mocked SkillRepository skillRepository,
@Mocked EmployerRepository employerRepository,
@Mocked JobRepository jobRepository,
@Mocked Job job,
@Mocked Errors errors)
throws ClassNotFoundException, NoSuchMethodException, NoSuchFieldException, IllegalAccessException, InvocationTargetException {
Class homeControllerClass = getClassByName("controllers.HomeController");
Method processAddJobFormMethod = homeControllerClass.getMethod("processAddJobForm", Job.class, Errors.class, Model.class, int.class, List.class);
new Expectations() {{
skillRepository.findAllById((List<Integer>) any);
job.setSkills((List<Skill>) any);
}};
Model model = new ExtendedModelMap();
HomeController homeController = new HomeController();
Field skillRepositoryField = homeControllerClass.getDeclaredField("skillRepository");
skillRepositoryField.setAccessible(true);
skillRepositoryField.set(homeController, skillRepository);
Field employerRepositoryField = homeControllerClass.getDeclaredField("employerRepository");
employerRepositoryField.setAccessible(true);
employerRepositoryField.set(homeController, employerRepository);
Field jobRepositoryField = homeControllerClass.getDeclaredField("jobRepository");
jobRepositoryField.setAccessible(true);
jobRepositoryField.set(homeController, jobRepository);
processAddJobFormMethod.invoke(homeController, job, errors, model, 0, new ArrayList<Skill>());
}
錯誤
Missing 1 invocation to:
org.springframework.data.repository.CrudRepository#findAllById(any Iterable)
on mock instance: org.launchcode.techjobs.persistent.models.data.$Impl_SkillRepository@7030449d
Missing 1 invocation to:
org.springframework.data.repository.CrudRepository#findAllById(any Iterable)
on mock instance: org.launchcode.techjobs.persistent.models.data.$Impl_SkillRepository@7030449d
at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: Missing invocations
at org.launchcode.techjobs.persistent.TestTaskFour$1.<init>(TestTaskFour.java:143)
at org.launchcode.techjobs.persistent.TestTaskFour.testProcessAddJobFormHandlesSkillsProperly(TestTaskFour.java:142)
... 1 more
org.launchcode.techjobs.persistent.TestTaskFour > testProcessAddJobFormHandlesSkillsProperly(SkillRepository, EmployerRepository, JobRepository, Job, Errors) FAILED
mockit.internal.expectations.invocation.MissingInvocation
Caused by: mockit.internal.expectations.invocation.ExpectationError at TestTaskFour.java:143
1 test completed, 1 failed
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':test'.
> There were failing tests. See the report at: file:///Users/JK/Desktop/LaunchCode/LC_Java/assignment-4-techjobs-persistent-edition-suchunkang0822/build/reports/tests/test/index.html
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Get more help at https://help.gradle.org
BUILD FAILED in 2s
4 actionable tasks: 1 executed, 3 up-to-date
很難說,因為您只展示了測試,而不是測試 class 的 rest。 但是,我猜在經過測試的 class 上,“employerRepository”和“skillsRepository”可能是自動連接的。 假設是這樣,那么您可能想要使用“@Tested”和“@Injectable”而不是“@Mocked”。 也就是說,您的 class 是“@Tested”,它在構造時需要的東西作為@Injectable 傳遞。
public class DummyTest {
@Tested public HomeController ctrl;
@Injectable protected SkillRepository skillRepository;
@Injectable protected EmployerRepository employerRepository;
@Injectable protected JobRepository jobRepository;
@Test public void testSomething(..) { .. }
}
您的第二個問題是您實際上並沒有使用您創建的模擬進行測試。 在您的測試中,您通過 new 創建了一個“真正的” HomeController,然后通過反射在其上調用了 processAddJobForm(..)。 這要簡單得多:
@Test
public void testProcessAddJobFormHandlesSkillsProperly (
@Mocked Job job,
@Mocked Errors errors)
{
new Expectations() {{
skillRepository.findAllById((List<Integer>) any);
job.setSkills((List<Skill>) any);
}};
Model model = new ExtendedModelMap();
homeController.processAddJobForm(job, errors, model, 0, new ArrayList<Skill>());
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.