有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何对长函数进行单元测试?

如果我有一个很长的代码方法,它从2个或3个不同的源收集数据并返回结果。我如何重构它,使它更易于单元测试?这个方法是一个Web服务,我想从客户机代码中调用一次来收集所有数据

我可以将一些部分重构成更小的方法,这些方法更易于测试。但是当前的方法仍然会调用这5个方法,并且不太容易测试。假设Java是一种编程语言,有没有一种模式可以使这种代码可测试


共 (2) 个答案

  1. # 1 楼答案

    “大”方法的测试将类似于集成测试,在集成测试中可以模拟较小的方法

    如果可以将“big”方法分为五个独立的方法,那么“big”方法可以进一步分为语义上/上下文上有意义的独立方法组

    然后,您可以为“big”方法模拟较大的孤立方法分组

  2. # 2 楼答案

    这是一个非常常见的测试问题,我遇到的最常见的解决方案是将数据源与使用依赖项注入的数据的代码分离。这不仅支持良好的测试,而且在使用外部数据源时通常是一个良好的策略(良好的职责分离、隔离集成点、促进代码重用是其中的一些原因)

    您需要进行的更改如下所示:

    • 对于每个数据源,创建一个接口来定义如何访问该数据源中的数据,然后将返回数据的代码分解为一个单独的类,该类实现了这一点
    • 依赖项将数据源注入包含“long”函数的类中
    • 对于单元测试,为每个数据源注入一个模拟实现

    下面是一些代码示例,展示了这将是什么样子-请注意,这段代码只是对模式的说明,您需要一些更合理的名称。值得研究这种模式,并进一步了解依赖注入&;模拟-两个最强大的武器在单位测试兵工厂

    数据源

    public interface DataSourceOne {
        public Data getData();
    }
    
    public class DataSourceOneImpl implements DataSourceOne {
        public Data getData() {
            ...
            return data;
        }
    }
    
    public interface DataSourceTwo {
        public Data getData();
    }
    
    public class DataSourceTwoImpl implements DataSourceTwo {
        public Data getData() {
            ...
            return data;
        }
    }
    

    使用长方法上课

    public class ClassWithLongMethod {
        private DataSourceOne dataSourceOne;
        private DataSourceTwo dataSourceTwo;
    
        public ClassWithLongMethod(DataSourceOne dataSourceOne,
                                   DataSourceTwo dataSourceTwo) {
            this.dataSourceOne = dataSourceOne;
            this.dataSourceTwo = dataSourceTwo;
        }
    
        public Result longMethod() {
            someData = dataSourceOne.getData();
            someMoreData = dataSourceTwo.getData();
            ...
            return result;
        }
    }
    

    单元测试

    import org.junit.Test;
    
    import static org.mockito.Mockito.mock;
    import static org.mockito.Mockito.when;
    
    public class ClassWithLongMethodTest {
    
        @Test
        public void testLongMethod() {
    
            // Create mocked data sources which return the data required by your test
            DataSourceOne dataSourceOne = mock(DataSourceOne.class);
            when(dataSourceOne.getData()).thenReturn(...);
            DataSourceTwo dataSourceTwo = mock(DataSourceTwo.class);
            when(dataSourceTwo.getData()).thenReturn(...);
    
            // Create the object under test using the mocked data sources
            ClassWithLongMethod sut = new ClassWithLongMethod(dataSourceOne,
                                                              dataSourceTwo);
    
            // Now you can unit test the long method in isolation from it's dependencies
            Result result = sut.longMethod();
    
            // Assertions on result
            ...
        }
    }
    

    请原谅(并纠正)任何语法错误,我现在不太会写java