65607


JavaEEを用いて部署管理アプリを作成しており、その中でモックテストコードを作成しております。  
その中の一部、データ保存処理（saveテスト）で、No argument value was captured!とエラーが出てしまいました。  
下記コードで何か問題があるようなのですが、原因がお分かりになりますでしょうか？  
教えて頂けましたら幸いです。宜しくお願いします。

* * *

**エラーメッセージ**

[code]

    org.mockito.exceptions.base.MockitoException: 
    No argument value was captured!
    You might have forgotten to use argument.capture() in verify()...
    ...or you used capture() in stubbing but stubbed method was not called.
    Be aware that it is recommended to use capture() only with verify()
    
    Examples of correct argument capturing:
        ArgumentCaptor<Person> argument = ArgumentCaptor.forClass(Person.class);
        verify(mock).doSomething(argument.capture());
        assertEquals("John", argument.getValue().getName());
    
[/code]

**現状のソースコード**

[code]

        @RunWith(CdiRunner.class)
        public static class SaveTest {
    
            @Inject
            private EditLogicImpl logic;
    
            @Mock
            @Produces
            private DeptDao dao;
    
                /**
             * 登録成功
             */
            @Test
            public void testSaveInsert() {
                // モックの戻り値設定
                long id = 1;
                Integer deptNo = 1;
                String deptName = "総務部";
                String loc = "新宿";
                Integer versionNo = 1;
                Dept dept = new Dept();
                dept.setId(id);
                dept.setDeptNo(deptNo);
                dept.setDeptName(deptName);
                dept.setLoc(loc);
                dept.setVersionNo(versionNo);
    
                // 実行設定
                EditBean bean = new EditBean();
                bean.setDisableId(false);
                bean.setDisableDeptNo(false);
                bean.setId(id);
                bean.setDeptNo(deptNo);
                bean.setDeptName(deptName);
                bean.setLoc(loc);
                bean.setVersionNo(versionNo);
    
                ArgumentCaptor<Dept> ac = ArgumentCaptor.forClass(Dept.class);
                doNothing().when(dao).insert(ac.capture());
    
                //try{
                    logic.save(bean);
                    Dept arg = ac.getValue();
                    // 結果を確認
                    assertEquals((long)id, (long)arg.getId());
                    assertEquals(deptNo, arg.getDeptNo());
                    assertEquals(deptName, arg.getDeptName());
                    assertEquals(loc, arg.getLoc());
                    assertEquals((int)versionNo,(int)arg.getVersionNo());
                    // 呼び出し回数と引数を確認
                    verify(dao, times(1)).insert(arg);
                    verify(dao, times(0)).update(null);
                    verify(dao, times(0)).findDeptNo(arg.getDeptNo());
                    verify(dao, times(0)).findVersionNo(arg.getVersionNo());
    
                //}catch(NullPointerException e){
                //  Dept arg = ac.getValue();
                //  verify(dao, times(0)).insert(arg);
                //}
            }
        }
    
    
[/code]

[code]

        /**
         * 保存処理
         * @param bean 編集画面のバッキングBean
         */
        @Override
        public boolean save(EditBean bean){
            Dept dept = new Dept();
            dept.setId(bean.getId());
            dept.setDeptName(bean.getDeptName());
            dept.setDeptNo(bean.getDeptNo());
            dept.setLoc(bean.getLoc());
            if(bean.getVersionNo() != null){
                dept.setVersionNo(bean.getVersionNo());
            }else{
                dept.setVersionNo(0);
            }
    
            if(bean.isDisableId()){
                // deptNo非重複時エラー
                if((dao.findDeptNo(bean.getDeptNo())) == null){
                    FacesContext context = FacesContext.getCurrentInstance();
                    context.addMessage("", CommonUtil.getFacesInfoMessage("messages.add.error.dept.notfound"));
                    return false;
                // 更新
                }else{
                    // versionNo不一致時エラー
                    if(bean.getVersionNo() != dao.findVersionNo(bean.getDeptNo())){
                        FacesContext context = FacesContext.getCurrentInstance();
                        context.addMessage("", CommonUtil.getFacesInfoMessage("messages.add.error.dept.exclusive"));
                        // データ再取得、取得データ画面表示
                        Dept dept2 = dao.findById(bean.getId());
                        bean.setId(dept2.getId());
                        bean.setDeptName(dept2.getDeptName());
                        bean.setDeptNo(dept2.getDeptNo());
                        bean.setLoc(dept2.getLoc());
                        bean.setVersionNo(dept2.getVersionNo());
                        bean.setDisableId(true);
                        bean.setDisableDeptNo(true);
                        return false;
                    }
                    // versionNo一致時 更新処理
                    else{
                        dao.update(dept);
                        bean.setVersionNo(dept.getVersionNo());
                        return true;
                    }
                }
            }else{
                // deptNo重複時エラー
                if((dao.findDeptNo(bean.getDeptNo())) != null){
                    FacesContext context = FacesContext.getCurrentInstance();
                    context.addMessage("", CommonUtil.getFacesInfoMessage("messages.add.error.dept.duplicate"));
                    return false;
                }else{
                    // 新規登録
                    dao.insert(dept);
                    bean.setDisableId(true);
                    bean.setDisableDeptNo(true);
                    return true;
                }
            }
        }
    
[/code]


CC BY-SA 4.0
2020-04-13T08:03:42.307
65584
2020-04-14T08:55:38.330
2020-04-14T08:29:57.723
3060
question
java-ee
No argument value was captured!のエラー解消法について

[code]

    ArgumentCaptor<Dept> ac = ArgumentCaptor.forClass(Dept.class);
    doNothing().when(dao).insert(ac.capture());
    
    //try{
        logic.save(bean);
        Dept arg = ac.getValue();
        // 結果を確認
    (後略)
    
[/code]

このテストコードは、

[code]

    // 新規登録
    dao.insert(dept);
    bean.setDisableId(true);
    bean.setDisableDeptNo(true);
    return true;
    
[/code]

の、新規登録処理 `dao.insert(dept);` の引数 `dept`
を検証することを想定したものだと思われますが、Mockitoが出力しているエラーメッセージ

> No argument value was captured!

が今回意味するところは、「新規登録処理を行っていない(`insert`メソッドが呼ばれていない)ので得られるべき値 `dept` が得られていない」です。  
ただ、今回のコードを見た限りでは私には `insert` が呼ばれない理由はよくわかりませんでした。

実際のところどうなっているかは、デバッガでステップ実行を行うことで確認できるでしょう。


CC BY-SA 4.0
2020-04-14T08:29:40.167
65607
2020-04-14T08:55:38.330
2020-04-14T08:55:38.330
2808
2808
65584
answer