模拟具有多个模拟依赖项的类作为构造函数

时间:2017-05-02 13:11:51

标签: java unit-testing mocking mockito

我一直试图模仿我的服务/商务课程来开始测试我的应用程序但是有许多依赖关系"在其他类上,主要是存储库和传递给那些存储库的存根。 我一直试图设置它以便能够对我的服务进行单元测试,但我一直在收到错误,而且我真的不知道我的设置是否正确:

我还没有包含接口,因为我认为没有必要,但如果需要可以。

    public abstract class  DemoRepo<T> implements Repository<T> {

        private dbStub stub;
        private Class<T> clazz;


        public DemoRepo(DbStub stub,Class<T> clazz){
            this.clazz = clazz;
            this.stub = stub;
        }

        @Override
        public void add(T item) {
            stub.inSert(item);
        }
        @Override
        public void update(T item) {
            stub.update(item);
        }
        ...

    }

然后这两个存储库扩展了每个类的抽象类

    public class Class1Repo extends DemoRepo<Class1> {
        public Class1Repo(DbStub stub) {
            super(stub,Class1.class);
        }
    }


    public class Class2Repo extends DemoRepo<Class2> {
        public Class2Repo(DbStub stub) {
            super(stub,Class2.class);
        }
    }

然后对于使用之前创建的2个存储库的抽象服务也一样。

    public abstract class AbstractService implements ClassService {
        private Repository<Class1> class1Repository;
        private Repository<Class2> class2Repository;

        public AbstractService(Repository<Class1> class1Repository, Repository<Class2> class2Repository) {
            this.class1Repository = class1Repository;
            this.class2Repository = class2Repository;
        }

        public boolean itemValiation(String itemId){
            Class1 item = class1Repository.findOne(itemId);
            item.setValidated(true);
            class1Repository.update(item);
            return true;
        }

        .....

    }

最后这个服务是我试图测试的:

    public class DemoImplService extends AbstractService {

        public DemoImplService(Class1Repo c1repo,Class2Repo c2repo){
            super(c1repo, c2repo);
        }
    }

但是你可以看到我需要传递2个嘲笑的存储库,这些存储库本身就是从一个被模拟的存储库中实例化的。存根&#34;那就是我的问题。

我尝试过很多不同的方式,但这是最近给我带来麻烦的方法:

class DemoImplServiceTest {
    @Mock
    private DbStub stub;

    private DemoImplService service;

    @InjectMocks
    private Class1Repo repo;

    @InjectMocks
    private Class2Repo repor;


    @Before
    public void setUp() {
        MockitoAnnotations.initMocks( this );
        Class1Repo repo = new Class1Repo(stub);
        Class2Repo repor = new Class2Repo(stub);
        DemoImplService service = new DemoImplService(repo,repor);
    }

    @Test
    void itemValiation() {
        Class1 c1 = new Class1();
        **when (repo.findOne("1")).thenReturn(c1);**
        //java.lang.NullPointerException
    }

}

我的逻辑是尝试使用mock / injectmocks机制,然后只是模拟存储库,因为我真的不需要嘲笑存根,但它没有编译我得到{ {1}}

我还尝试使用java.lang.NullPointerException设置2个存储库,但我甚至没有编译这样的方式,所以我放弃了。

更新:

新班级

ReflectionTestUtils.setField

这一行class DemoImplServiceTest { @Mock private Class1Repo repo; @Mock private Class2Repo repor; @InjectMocks private DemoImplService service; @Before public void setUp() { MockitoAnnotations.initMocks( this ); Class1 object = new Class1(); when (repo.findOne("1")).thenReturn(object); } @Test void itemValiation() { boolean updated = service.itemValiation("1"); assertTrue( updated ); verify( repo ).findOne("1"); ArgumentCaptor<Class1> class1Captor = ArgumentCaptor.forClass( Class1.class ); verify( repo ).update( class1Captor.capture() ); Class1 updatedCclass1 = class1Captor.getValue(); assertTrue( Class1.isValidated() ); } 是最令人意想不到的:java.lang.NullPointerException

我试过宣布

boolean updated = service.itemValiation("1");

Class1 object = new Class1(); when (repo.findOne("1")).thenReturn(object); func中,但没有改变任何内容

最后一件事是,如果我在测试函数中添加方法void itemValiation(),我会在该行service = new DemoImplService(repo,repor);的itemValidation方法内的AbstractService中找到一个不同的空指针异常。

更新2

没有实例化类的完整异常:

class1Repository.update(item);

1 个答案:

答案 0 :(得分:1)

我认为您应该在要测试的类上使用@InjectMocks,并在该类的依赖项上使用@Mock。

class DemoImplServiceTest {
    @InjectMocks
    private DemoImplService service;

    @Mock
    private Class1Repo repo;

    @Mock
    private Class2Repo repor;


    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    void testMethod() {
        ...
        ...
    }

}