Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何模拟私有内部类_Java_Unit Testing_Spring Mvc_Mocking_Mockito - Fatal编程技术网

Java 如何模拟私有内部类

Java 如何模拟私有内部类,java,unit-testing,spring-mvc,mocking,mockito,Java,Unit Testing,Spring Mvc,Mocking,Mockito,我有一个spring应用程序,我想在这样一个控制器上创建一个单一测试。问题是包装器类是一个私有的内部类,所以在测试中包装器不被理解。是否可以在不更改控制器类的情况下使用Mockito对其进行模拟。我可以使用prepareData()获取对象的实例,但我不知道是否可以使用它来模拟该对象 谢谢 @Controller public class Controller { private class Wrapper { private Object1 field1;

我有一个spring应用程序,我想在这样一个控制器上创建一个单一测试。问题是包装器类是一个私有的内部类,所以在测试中包装器不被理解。是否可以在不更改控制器类的情况下使用Mockito对其进行模拟。我可以使用prepareData()获取对象的实例,但我不知道是否可以使用它来模拟该对象

谢谢

@Controller
public class Controller {

    private class Wrapper {
        private Object1 field1;
        private Object2 field2;
        private Object1 method1(){
           ...
        }
        private Object2 method1(){
           ...
        }
    }

    @ModelAttribute("data")
    public Wrapper prepareData() {
            return new Wrapper ();
}

    public String save(@ModelAttribute("data") Wrapper wrapper, BindingResult result, Model model){
        ...
    }
}
所以在我的测试中,我会有这样的东西

@Test
public void usernameEmpty(){

    BindingResult result = Mockito.mock(BindingResult.class);
    Model model = Mockito.mock(Model.class);
    Wrapper data = //how to mock it
    when(data.method1()).then(new Foo1());
    when(data.method2()).then(new Foo2());
    String returned = controller.save(data, result, model);
    ....
}

您的测试是在方法上进行的,但它测试整个类的行为。如果您的内部类是私有的,那么它是一个实现细节。一些测试不应该知道的事情。在这个内部类中有很多行为,你想独立测试它,也许你应该把它公开,并与这个类分开

也许你会想:但是。。。要测试的代码太多了(一个非常大的不可分割的东西),我不能测试更小的东西吗?好。。。对测试驱动的开发要求只在添加更多测试的情况下进行最少的实现并添加更多代码。因此,您从一些测试和最小实现开始,并对它们进行改进,直到测试包含了所有规范和代码以及所有实现


所以不要担心私有的内部类。测试你的班级合同

我问你为什么要这么做?您可能最终测试错误的代码。如果内部类具有依赖项(可能是通过控制器获得的?),则模拟这些依赖项。等待你的代码编译吗?若包装器是私有类,你们能用它作为公共方法的参数吗?@MartinhoFernandes我是测试新手。我只是想对save方法进行测试,所以我需要模拟包装器对象,以便在调用某些方法时可以定义返回对象。是的,控制器进行编译(测试没有,但这就是问题所在——我不能在测试中使用包装器类)。也许有更好的方法可以做到这一点。Java又一次让我感到惊讶(消极的方面)。如果手头没有Java编译器,我将无能为力:(无论如何,即使允许,我也不认为拥有一个需要私有知识的公共方法是一个好的设计。它破坏了封装。你将如何在实际代码中使用该方法?可能吗?@Martinho Fernandes你是对的,我想我会将其改为public,祝你在单元测试中好运!这给了你很大的信心和信心。)d在不(不适当地)破坏东西的情况下进行更改的能力!这不是很好-这将是集成测试。你破坏了测试驱动开发的主要原则之一-测试应该很简单!是的。但是TDD是一种开发方法:首先编写测试,然后编写代码。在这种情况下,OP可能会得到另一种设计(更简单、更模块化),而不是获得私有内部类。在这种情况下,它只是测试一个已经存在的代码。他说:我同意这不是一个简单的测试,但私有内部类不能从容器类中提取,所以尽管它不简单,但它不是一个集成测试IMHO(无论如何,重要的部分是“测试”:我不这么认为。例如:若文件详细阐述了一些信息,它有时需要内部缓存,通常它可以像私有内部类一样。