JUnit测试类执行以下操作的代码(junit test class for the followi

2019-06-27 20:06发布

如何嘲笑的电话对象的对象。

代码波纹管,

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());
  }
}

谢谢

Answer 1:

首先,我要作出一些假设。 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 。 同样的事情也会在此时进行。 注入和模拟/设置的对象。



Answer 2:

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

如果您需要模拟一个new ,你需要一个工厂传递给对象,然后嘲笑你的工厂。 这方面的一个非常常见的例子是,当你需要模拟Date对象,这是在此的其他问题很好解释: 如何嘲笑Date类的默认构造函数 (检查的第一个答案)。

作为一个侧面说明,称电话的实例name ...嗯,不看的权利。



Answer 3:

类嘲讽是很容易使用EasyMock的 。 它利用CGLIB的内部执行类嘲讽。 EasyMock的既可以模拟接口类(类嘲讽)。 见文档 。

所以,让你的模拟电话,只需拨打createMock(Phone.class):

Phone phoneMock = createMock(Phone.class);

作为奥古斯托说,它是不是真的好设计,充分利用班嘲讽的虽然。 更好的办法是对接口编程和使用依赖注入框架。



Answer 4:

所以,你需要做的下列选项之一注入嘲笑成田nameuserdao (我会假设你可以使用new Phone领域实例,而不是在方法创建的一个。

  1. 不要直接调用构造函数在代码中,而是通过制定者使用字段注入。 这将使你的测试,这两类提供嘲笑实例。 如果你必须在方法创建一个新的实例,然后考虑使用一个工厂可以嘲笑。

  2. 提供两个字段默认范围setter方法。 这些方法将在地方仅用于测试目的。

  3. 用便餐设置字段嘲笑实例。 一个简单的方法就是使用Spring的ReflectionTestUtils。

一旦其中之一是在地方,你可以提供嘲笑实例(可能使用的Mockito)来驱动你要测试的行为。 我建议选择1是最好的,如果fesible,然后选择3。但是,缺点期权3是测试依赖私有字段的名称。

然后...

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

objectUnderTest.handleUser(...);


文章来源: junit test class for the following code
标签: java junit