【问题标题】:how to inject mock without using @injectmocks如何在不使用@injectmocks 的情况下注入模拟
【发布时间】:2023-04-09 02:07:01
【问题描述】:

我有以下课程

public class One {
    private Map<String, String> nodes = new HashMap<String, String>();

    public void addNode(String node, String nodefield){
        this.nodes.put(node, nodefield);
    }
}

我想写一个测试类来测试addNode方法,有以下内容:

@RunWith(MockitoJUnitRunner.class)
public class OneTest {
    @InjectMocks
    private One one = new One();

    @Mock
    Map<String, String> nodes;

    @Test
    public void testAddNode(){
        one.addNode("mockNode", "mockNodeField");
        Mockito.verify(nodes).put("mockNode","mockNodeField");
    }
}

有效。但我想知道是否有办法在不使用@InjectMocks 的情况下做到这一点,如下所示

public class OneTest {

    private One one;

    @Test
    public void testAddNode(){
        Map<String, String> nodes = Mockito.mock(Map.class);

        one = Mockito.injectmocks(One.class, nodes); // or whatever equivalent methods are

        one.addNode("mockNode", "mockNodeField");
        Mockito.verify(nodes).put("mockNode","mockNodeField");
    }
}

【问题讨论】:

    标签: java unit-testing testing mocking mockito


    【解决方案1】:

    如何通过将映射作为依赖项注入来更改类?这使得测试变得更容易,并为您提供了能够使用 Map 接口实现的额外好处,例如:

      public class One {
    
        private Map<String, String> nodes;
    
        public One(Map<String, String> nodes) {
    
            this.nodes = nodes;
    
        }
    
        public void addNode(String node, String nodefield){
    
            this.nodes.put(node, nodefield);
    
        }
    }
    

    然后进行测试:

    Map mockMap = Mockito.mock(Map.class);
    
    One one = new One(mockMap);
    
    one.addNode("mockNode", "mockNodeField");
    
    Mockito.verify(mockMap).put("mockNode","mockNodeField");
    

    【讨论】:

    • 是的,我也想过。但我实际上正在为一个不是我编写的课程编写测试。该类已经设置了一个构造函数。上面的代码只是用于解释的实际类的更简单版本。那么有没有办法在不改变原有类的情况下为addNode方法写一个测试呢?
    【解决方案2】:

    好的,我通过使用 PowerMockito 而不是普通的 Mockito 解决了这个问题。

    public class OneTest {
    
        private One one;
    
        @Test
        public void testAddNode(){
            HashMap nodes = PowerMockito.mock(HashMap.class);
            PowerMockito.whenNew(HashMap.class).withNoArguments().thenReturn(nodes);
    
    
            One one = new One(); 
    
            one.addNode("mockNode", "mockNodeField");
            Mockito.verify(nodes).put("mockNode","mockNodeField");
        }
    }
    

    但是,我真的不知道 PowerMockito 做了什么而 Mockito 没有做些什么来使它工作。

    【讨论】:

    • 您真正需要的是一个反射实用程序来访问私有属性。一旦您可以访问它们,您就可以使用 spy 或 mock。间谍更好,因为您只想专注于一个实例。如果您仍在使用 1.x 版本,Mockito 有内部类 Whitebox。如果你碰巧使用 Spring,Spring 就有 ReflectionUtil。
    • 我最近重新审视了这个问题,发现 ReflectionTestUtils 是一个更好的解决方案。我在这里找到了一个很好的阅读并想分享:mrhaki.blogspot.com/2010/09/…。我试图远离 PowerMock,因为我读到这不是最佳实践。感谢您的信息!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多