Java 以下代码的junit测试类
如何为Phone对象模拟对象 下面的代码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
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看起来不太对劲。你没有。模拟的规则之一是:永远不要模拟实体或值对象。如果你需要打破这个规则,这意味着你可能有一个设计缺陷
如果需要模拟一个新的,则需要将工厂传递给对象,然后模拟工厂。一个非常常见的例子是当您需要模拟日期对象时,这在另一个问题中得到了很好的解释:(检查第一个答案)
作为旁注,调用Phonename
…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()
为“测试”,您返回“完成”,或者返回“否”