如何嘲笑的电话对象的对象。
代码波纹管,
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());
}
}
谢谢
首先,我要作出一些假设。 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()
是“测试”,并返回“完成”,或者它是不是和你返回“失败”。
那么如何设置设置“ getA
”。 有一两件事是肯定的,我们需要能够设置“名称”,从测试。 为此,我们需要“注入”(我们可以做到这一点其他的一些方法,但我喜欢注射)。 我会用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
是。 如果是复杂的,比我们想看看以某种方式“facking”它(嘲弄,存根等)。 这可能是一段代码,你写的,也可能是使用像Mocketo的工具。
如果电话的对象是简单的,并且具有或能够产生一个“ setA
”的方法,那么就使用它。
我相信以后你会需要userdao
。 同样的事情也会在此时进行。 注入和模拟/设置的对象。
你不知道。 一个嘲讽的规则是:你永远模拟实体或值对象。 如果您需要打破这个规则,这意味着你可能有一个设计缺陷。
如果您需要模拟一个new
,你需要一个工厂传递给对象,然后嘲笑你的工厂。 这方面的一个非常常见的例子是,当你需要模拟Date对象,这是在此的其他问题很好解释: 如何嘲笑Date类的默认构造函数 (检查的第一个答案)。
作为一个侧面说明,称电话的实例name
...嗯,不看的权利。
类嘲讽是很容易使用EasyMock的 。 它利用CGLIB的内部执行类嘲讽。 EasyMock的既可以模拟接口和类(类嘲讽)。 见文档 。
所以,让你的模拟电话,只需拨打createMock(Phone.class):
Phone phoneMock = createMock(Phone.class);
作为奥古斯托说,它是不是真的好设计,充分利用班嘲讽的虽然。 更好的办法是对接口编程和使用依赖注入框架。
所以,你需要做的下列选项之一注入嘲笑成田name
和userdao
(我会假设你可以使用new Phone
领域实例,而不是在方法创建的一个。
不要直接调用构造函数在代码中,而是通过制定者使用字段注入。 这将使你的测试,这两类提供嘲笑实例。 如果你必须在方法创建一个新的实例,然后考虑使用一个工厂可以嘲笑。
提供两个字段默认范围setter方法。 这些方法将在地方仅用于测试目的。
用便餐设置字段嘲笑实例。 一个简单的方法就是使用Spring的ReflectionTestUtils。
一旦其中之一是在地方,你可以提供嘲笑实例(可能使用的Mockito)来驱动你要测试的行为。 我建议选择1是最好的,如果fesible,然后选择3。但是,缺点期权3是测试依赖私有字段的名称。
然后...
Phone phone = Mockito.mock(Phone.class);
Mockito.when(phone.getA()).thenReturn("blah");
objectUnderTest.setPhone(phone);
objectUnderTest.handleUser(...);