我一直在尝试模拟我的服务/业务类来开始测试我的应用程序,但是对其他类有很多“依赖项”,主要是存储库和传递到这些存储库的 stub 。 我一直在尝试进行设置,以便能够对我的服务进行单元测试,但我不断收到错误,而且我真的不知道我的设置是否正确:

我没有包括接口(interface),因为我觉得没有必要,但如果需要的话可以。

    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 个模拟存储库,它们本身是从模拟“ stub ”实例化的,这就是我的问题。

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

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 
    } 
 
} 

我这里的逻辑是尝试使用模拟/注入(inject)模拟机制,然后只是模拟存储库,因为我实际上不需要模拟 stub ,但它没有编译我得到java.lang.NullPointerException

我还尝试使用 ReflectionTestUtils.setField 设置 2 存储库,但我什至没有以这种方式进行编译,所以我放弃了。

<小时 />

更新:

新类(class)

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() ); 
} 

这行 boolean Updated = service.itemValiation("1"); 是失败的:java.lang.NullPointerException

我尝试过声明

    Class1 object = new Class1(); 
    when (repo.findOne("1")).thenReturn(object); 

void itemValiation()函数内,但这并没有改变任何东西

最后一件事是,如果我在测试函数中添加方法 service = new DemoImplService(repo,repor); 我会得到一个不同的空指针异常,这次位于 AbstractService 中该行的 itemValidation 方法 class1Repository.update(item);

更新2

未实例化类的完整异常:

    java.lang.NullPointerException 
        at com.jd.mypackage.test.services.ImplServiceTest.itemValiation(ImplServiceTest.java:187) 
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
        at java.lang.reflect.Method.invoke(Method.java:497) 
        at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:316) 
        at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:114) 
        at org.junit.jupiter.engine.descriptor.MethodTestDescriptor.lambda$invokeTestMethod$6(MethodTestDescriptor.java:171) 
        at org.junit.jupiter.engine.descriptor.MethodTestDescriptor$$Lambda$141/655381473.execute(Unknown Source) 
        at org.junit.jupiter.engine.execution.ThrowableCollector.execute(ThrowableCollector.java:40) 
        at org.junit.jupiter.engine.descriptor.MethodTestDescriptor.invokeTestMethod(MethodTestDescriptor.java:168) 
        at org.junit.jupiter.engine.descriptor.MethodTestDescriptor.execute(MethodTestDescriptor.java:115) 
        at org.junit.jupiter.engine.descriptor.MethodTestDescriptor.execute(MethodTestDescriptor.java:57) 
        at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.lambda$execute$1(HierarchicalTestExecutor.java:81) 
        at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$$Lambda$109/981661423.execute(Unknown Source) 
        at org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66) 
        at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:76) 
        at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.lambda$execute$1(HierarchicalTestExecutor.java:91) 
        at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$$Lambda$109/981661423.execute(Unknown Source) 
        at org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66) 
        at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:76) 
        at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.lambda$execute$1(HierarchicalTestExecutor.java:91) 
        at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$$Lambda$109/981661423.execute(Unknown Source) 
        at org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66) 
        at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:76) 
        at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:51) 
        at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:43) 
        at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:137) 
        at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:87) 
        at org.junit.platform.launcher.Launcher.execute(Launcher.java:93) 
        at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:61) 
        at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51) 
        at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242) 
        at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70) 

请您参考如下方法:

我认为您应该在要测试的类上使用@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() { 
        ... 
        ... 
    } 
 
} 


评论关闭
IT干货网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!