【问题标题】:Mock a nested class with constructor parameters and test the methods使用构造函数参数模拟嵌套类并测试方法
【发布时间】:2019-09-05 19:31:26
【问题描述】:

我正在尝试模拟具有嵌套类的类。该嵌套类带有构造函数参数。 当我尝试使用模拟而不是模拟进行测试时,实际方法正在执行。

我在外部类上做了@InjectMocks,在内部类上做了@Mock。

//Actual Class to test using Mockito.

public class ClassA {

public void initMethod(String s1, String s2, String s3, String s4) throws Exception {

    ClassB objB = null;
    if (objB == null && s3 != null && s4 != null && s2 != null) {

        SampleUtil.KeyStorePasswordPair pair = SampleUtil.getKeyStorePasswordPair(s3, s4);


        objB = new ClassB(s1, s2, pair.keyStore, pair.keyPassword);

        try {
            objB.meth1();  //Note: meth1 and meth2 are void methods.  
            objB.meth2();  // These two methods only to be accessed. something like doNothing

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
}

我像往常一样尝试使用@Mock 调用该类,但实际方法 meth1() 正在被访问。

//Somthing which I tried 
@RunWith(MockitoJUnitRunner.class)
public class MockitoTest {


@InjectMocks
ClassA classA;

@Mock
ClassB classB;

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

@Test
public void testInitClient() throws Exception {
    // Setup

    // Run the test
    classA.initMethod("Lorem", "Ipsum", "TestStr1", "TestStr2");

    doNothing().when(classB).meth1(); // This is the line need to be mocked. But instead calling the actual method and executing
    // Verify the results
} 

需要模拟内部的 ClassB 方法,而不是访问真实的方法。

作为 mockito 的初学者,我想弄清楚这一点。但是对访问 void 方法等几点感到困惑,所以那时不能使用。使用参数等访问构造函数,

【问题讨论】:

    标签: java junit mockito powermock


    【解决方案1】:

    如果没有某种依赖注入,我认为这是不可能的。

    在这里,我修改了您的代码,使其行为符合您的要求。

    public class ClassA {
        // Needed so that it can be replaced with setter
        private ClassB objB;
    
        // Extract the generation of ClassB so that it can be prevented
        public void generateClassB(String s1, String s2) {
            this.objB = new ClassB(s1, s2);
        }
    
        public void initMethod(String s1, String s2, String s3, String s4) {
    
            objB = null;
            if (s3 != null && s4 != null && s2 != null) {
    
                SampleUtil.KeyStorePasswordPair pair = SampleUtil.getKeyStorePasswordPair(s3, s4);
    
                generateClassB(s1, s2);
    
                try {
                    objB.meth1();  //Note: meth1 and meth2 are void methods.
                    objB.meth2();  // These two methods only to be accessed. something like doNothing
    
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    
        public void setClassB(ClassB classB) {
            this.objB = classB;
        }
    }
    

    这是我用来测试结果的 ClassB 的实现。

    public class ClassB {
        private String s1;
        private String s2;
    
        public ClassB(String s1, String s2) {
            this.s1 = s1;
            this.s2 = s2;
        }
    
        public void meth1() {
            System.out.println(s1);
        }
    
        public void meth2() {
            System.out.println(s2);
        }
    }
    

    还有测试文件

    @RunWith(MockitoJUnitRunner.class)
    public class DemoApplicationTests {
        private ClassA classA;
        private ClassB classB;
    
        @Test
        public void testInitClient() {
            classA = Mockito.spy(ClassA.class);
            classB = Mockito.spy(new ClassB("a", "b"));
    
            Mockito.doNothing()
                    .when(classB)
                    .meth1();
    
            // This will replace the ClassA#generateClassB method call with the setter
            Mockito.doAnswer(args -> {
                classA.setClassB(classB);
                return null;
            }).when(classA).generateClassB(Mockito.any(), Mockito.any());
            classA.initMethod("a", "b", "c", "d");
        }
    }
    

    另一种更简洁的解决方案是将 ClassB 实例传递给 ClassA#initMethod。

    【讨论】:

      猜你喜欢
      • 2011-07-01
      • 2015-07-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多