簡體   English   中英

jmockit 期望不斷拋出丟失的調用,即使我正在調用它

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM