Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/376.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 以下代码的junit测试类_Java_Junit - Fatal编程技术网

Java 以下代码的junit测试类

Java 以下代码的junit测试类,java,junit,Java,Junit,如何为Phone对象模拟对象 下面的代码 public class Fortest { UserDao userdao = new UserDao(); Phone name = new Phone(); public String handleUser(User user) { String returncode="failed"; //User usr = new User("bob"); String username=user.getUsernam

如何为Phone对象模拟对象

下面的代码

public class Fortest {

  UserDao userdao = new UserDao();
  Phone name = new Phone();
  public String handleUser(User user) {

    String returncode="failed";
    //User usr = new User("bob");
    String username=user.getUsername();
    String pass=user.getPass();
    System.out.println("username and password : "+username+" : "+pass);

    Phone name = new Phone();
    String ph = name.getA();
    System.out.println("ph "+ph);

    if(ph.equalsIgnoreCase("test")){
      System.out.println("A "+ph);
      returncode="done";
    }
    System.out.println("returning "+returncode);

    return  returncode;
    //System.out.println("name "+name.toString());
    //System.out.println(name.getA());
  }
}

谢谢

你不需要。模拟的规则之一是:永远不要模拟实体或值对象。如果你需要打破这个规则,这意味着你可能有一个设计缺陷

如果需要模拟一个
新的
,则需要将工厂传递给对象,然后模拟工厂。一个非常常见的例子是当您需要模拟日期对象时,这在另一个问题中得到了很好的解释:(检查第一个答案)


作为旁注,调用Phone的实例
name
…mmm看起来不太对劲。

你没有。模拟的规则之一是:永远不要模拟实体或值对象。如果你需要打破这个规则,这意味着你可能有一个设计缺陷

如果需要模拟一个
新的
,则需要将工厂传递给对象,然后模拟工厂。一个非常常见的例子是当您需要模拟日期对象时,这在另一个问题中得到了很好的解释:(检查第一个答案)


作为旁注,调用Phone
name
…mmm的实例看起来不正确。

类模拟非常容易使用。它在内部使用cglib来执行类模拟。EasyMock可以模拟接口和类(类模拟)。看

因此,要获得手机模拟,只需调用createMock(Phone.class):


正如Augusto所说,使用类模拟并不是一个好的设计。更好的方法是面向接口编程并使用依赖注入框架。

类模拟非常容易使用。它在内部使用cglib来执行类模拟。EasyMock可以模拟接口和类(类模拟)。看

因此,要获得手机模拟,只需调用createMock(Phone.class):


正如Augusto所说,使用类模拟并不是一个好的设计。更好的方法是面向接口编程并使用依赖项注入框架。

因此,您需要执行以下选项之一,将mock注入字段
name
userdao
(我将假设您可以使用
新电话
字段实例,而不是在方法中创建的实例

>P>不直接调用代码中的构造函数,而是通过SETTER使用字段注入。这将允许您的测试提供两个类的模拟实例。如果必须在该方法中创建新实例,则考虑使用可被嘲笑的工厂。

  • 为这两个字段提供默认的范围设置器方法。这些方法仅用于测试目的

  • 使用Refection将字段设置为模拟实例。一种简单的方法是使用Spring的ReflectionTestUtils

  • 一旦其中一个到位,您就可以提供模拟实例(可能使用Mockito)来驱动您希望测试的行为。我建议,如果可行的话,选项1是最好的,然后是选项3。然而,选项3的缺点是测试依赖于私有字段的名称

    然后

    Phone phone = Mockito.mock(Phone.class);
    Mockito.when(phone.getA()).thenReturn("blah");
    objectUnderTest.setPhone(phone);
    
    objectUnderTest.handleUser(...);
    

    因此,您需要执行以下选项之一,将mock注入字段
    name
    userdao
    (我假设您可以使用
    newphone
    字段实例,而不是在方法中创建的实例

    >P>不直接调用代码中的构造函数,而是通过SETTER使用字段注入。这将允许您的测试提供两个类的模拟实例。如果必须在该方法中创建新实例,则考虑使用可被嘲笑的工厂。

  • 为这两个字段提供默认的范围设置器方法。这些方法仅用于测试目的

  • 使用Refection将字段设置为模拟实例。一种简单的方法是使用Spring的ReflectionTestUtils

  • 一旦其中一个到位,您就可以提供模拟实例(可能使用Mockito)来驱动您希望测试的行为。我建议,如果可行的话,选项1是最好的,然后是选项3。然而,选项3的缺点是测试依赖于私有字段的名称

    然后

    Phone phone = Mockito.mock(Phone.class);
    Mockito.when(phone.getA()).thenReturn("blah");
    objectUnderTest.setPhone(phone);
    
    objectUnderTest.handleUser(...);
    

    首先我要做一些假设。
    user.getUsername()
    &
    user.getPass()
    没有副作用。
    System.out.println
    对您来说并不重要

    这样,您的课程就变成:

    public class Fortest {
        Phone name = new Phone();
    
        public String handleUser(User user) {
            String ph = name.getA();
    
            if(ph.equalsIgnoreCase("test")){
                return "done";
            }
    
            return  "failed";
    
        } 
    }
    
    因此,您的测试有两个条件:
    phone.getA()
    为“test”,您返回“done”,否则返回“failed”

    那么如何设置“
    getA
    ”。有一件事是肯定的,我们需要能够从测试中设置“name”。为此,我们需要“注入”它(我们可以用许多其他方法来实现,但我喜欢注入)。我会使用Guice,很多人会使用Spring。有些人会使用其他注入框架之一。但在测试中,我们大多数人都会使用手动注入

    public class Fortest {
        Phone name;
        Fortest(Phone name) {
            this.name = name;
        }
    
        public String handleUser(User user) {
            String ph = name.getA();
    
            if(ph.equalsIgnoreCase("test")){
                return "done";
            }
    
            return  "failed";
    
        } 
    }
    
    
    public class TestFortest {
       @Before
       public void before() {
              name = ; //... 
              subject = new Fortest(name);
       }
    }
    
    现在,测试相当简单:

    public void whenTestModeIsEnabledThenReturnDone() {
         setPhoneIntoTestMode();
         String actual = subject.handleUser(null);
         assertEquals(actual, "done");
    }
    
    public void whenTestModeIsDisabledThenReturnFailed() {
         setPhoneIntoLiveMode();
         String actual = subject.handleUser(null);
         assertEquals(actual, "failed");
    }
    
    setPhoneIntoTestMode
    /
    setPhoneIntoLiveMode
    的实现将取决于
    Phone
    的复杂程度。如果它比我们在某种程度上“伪造”它要复杂(模拟、存根等)。这可能是您编写的一段代码,它可能使用类似Mocketo的工具

    如果Phone对象很简单,并且具有或可以具有“
    setA
    ”方法,则只需使用该方法即可


    我相信稍后您将需要
    userdao
    。在这一点上也会做同样的事情。注入并模拟/设置对象。

    首先,我将做一些假设。
    user.getUsername()
    &
    user.getPass()
    没有副作用。
    System.out.println
    对您来说并不重要

    这样,您的课程就变成:

    public class Fortest {
        Phone name = new Phone();
    
        public String handleUser(User user) {
            String ph = name.getA();
    
            if(ph.equalsIgnoreCase("test")){
                return "done";
            }
    
            return  "failed";
    
        } 
    }
    
    因此,您的测试有两个条件:
    phone.getA()
    为“测试”,您返回“完成”,或者返回“否”