编写Junit测试的测试用例

Glo*_*tor 2 java eclipse junit unit-testing

作为开发人员,我是单元测试的新手,并且需要编写测试用例来对以下代码进行单元测试.有人可以帮助我,并给我一些关于如何在eclipse中编写单元测试的指针.

private void handle(final DocumentEvent e) { 
    Document doc = e.getDocument(); 
    try { 
       String text = e.getDocument().getText(0, doc.getLength()); 

       if (text.length() >= maxMessageSize) { 
            try { 
               component.getHighlighter()
                        .addHighlight(maxMessageSize, text.length() + 1, painter); 
            } catch (BadLocationException ex) { 
               System.out.println(ex.getMessage()); 
            } 
       } else { 
            component.getHighlighter().removeAllHighlights(); 
       } 
    } catch (BadLocationException e1) { 
       System.out.println(e1.getMessage()); 
    } 
} 
Run Code Online (Sandbox Code Playgroud)

谢谢


更新

由于某种原因,当我运行测试用例时,我根本没有得到任何报道.我在这里做错了什么?进一步的研究表明我需要使用test.perform()方法来调用我想要测试的方法.这是正确的吗?你能建议吗?这是代码:

public class TestMaxLength {
  static final int maxMessageSize = 125;
  JTextPane textPane = new JTextPane();
  //***EasyMock varibles****
  private JTextComponent mockComponent;
  private MaxLength classUnderTest;
  private DocumentEvent mockEvent;
  private Document mockDocument;
  private Highlighter mockHighlighter;

  @Before public void setUp() {
    mockComponent = EasyMock.createMock(JTextComponent.class);
    mockEvent = EasyMock.createMock(DocumentEvent.class); 
    mockDocument = EasyMock.createMock(Document.class); 
    EasyMock.expect(mockEvent.getDocument()).andStubReturn(mockDocument);
    EasyMock.expect(mockDocument.getLength()).andReturn(256); 
    mockHighlighter = EasyMock.createMock(Highlighter.class); 
    EasyMock.expect(mockComponent.getHighlighter()).andReturn(mockHighlighter);
  }

  @Test public void testSetLength() { 
    MaxLength maxListener = new MaxLength(125); 
    maxListener.decorate(textPane);
  }

  @Test 
  public void testEmptyText() { 
    EasyMock.expect(mockDocument.getText(0, 1)).andStubReturn(""); 
    mockHighlighter.removeAllHighlights(); 
    EasyMock.replay(mockComponent, mockEvent, mockDocument, mockHighlighter);      
    classUnderTest.handle(mockEvent);      
    EasyMock.verify(mockComponent, mockEvent, mockDocument, mockHighlighter); 
  }     
}
Run Code Online (Sandbox Code Playgroud)

decorate(JtextComponent jComponent)方法存在于要测试的类(MaxLength)中,定义如下:

public final void decorate(final JTextComponent c) {
  //TODO throw exception if already decorating
  this.component = c;
  component.getDocument().addDocumentListener(this);
}
Run Code Online (Sandbox Code Playgroud) #

更新:

@Peter:管理发现它不是Component类的问题,而是我需要asm(http://forge.ow2.org/projects/asm).我还更改了代码,将2种方法合并为1种方法:

public void testEmptyText() 
{ 
maxSizeListener.decorate(mockComponent);
//mockHighlighter.removeAllHighlights(); 
EasyMock.replay(mockComponent, mockEvent, mockDocument, mockHighlighter); 
maxSizeListener.handle(mockEvent); 
EasyMock.verify(mockComponent, mockEvent, mockDocument, mockHighlighter); 
} 
Run Code Online (Sandbox Code Playgroud)

但现在我在验证时遇到了不同的错误:

java.lang.AssertionError: 
Expectation failure on verify:
getHighlighter(): expected: 1, actual: 0
at org.easymock.internal.MocksControl.verify(MocksControl.java:184)
at org.easymock.EasyMock.verify(EasyMock.java:2038)
at net.TestMaxLength.testEmptyText(TestMaxLength.java:98)
Run Code Online (Sandbox Code Playgroud)

这是在mockComponent上执行EasyMock.verify()语句时引起的.

Pét*_*rök 10

我建议使用模拟框架,例如EasyMock.模拟允许您使用所需的测试行为配置依赖项.在你的情况下,你需要一个模拟DocumentEvent和理想的另一个component,我想这是一个类成员.

单元测试的两个方面

  • 怎么测试,我...; e.将测试正确运行所需的正确状态的正确对象组装的技术细节(又称_test夹具),以及
  • 要测试什么,即要验证的场景.

怎么测试

Eclipse支持开箱即用的JUnit,因此您可以快速生成新的JUnit测试用例(在Project Explorer上下文菜单中:New - >(Other - >)JUnit - > JUnit Test Case),然后单击Run按钮运行它.

在您的情况下设置测试夹具看起来像这样,使用EasyMock(并假设您可以将组件作为构造函数参数传递给您的测试类):

private Component mockComponent;
private ClassUnderTest classUnderTest;
private DocumentEvent mockEvent;
private Document mockDocument;
private Highlighter mockHighlighter;

@Before
public void setUp() {
    mockComponent = createMock(Component.class);
    classUnderTest = new ClassUnderTest(mockComponent);
    mockEvent = createMock(DocumentEvent.class);
    mockDocument = createMock(Document.class);
    expect(mockEvent.getDocument()).andStubReturn(mockDocument);
    expect(mockDocument.getLength()).andReturn(1);
    mockHighlighter = createMock(Highlighter.class);
    expect(mockComponent.getHighlighter()).andReturn(mockHighlighter);
}

@Test
public void testEmptyText() {
    expect(mockDocument.getText(0, 1)).andStubReturn("");
    mockHighlighter.removeAllHighlights();
    replay(mockComponent, mockEvent, mockDocument, mockHighlighter);

    classUnderTest.handle(mockEvent);

    verify(mockComponent, mockEvent, mockDocument, mockHighlighter);
}
Run Code Online (Sandbox Code Playgroud)

此测试假设maxMessageSize默认情况下至少为1 - maxMessageSize测试的设置留给您作为练习,因为您发布的代码片段没有提供任何线索.

测试什么

您显示的方法从与事件关联的文档中获取文本,然后根据其长度,它执行不同的操作.我会写至少以下单元测试:

  • 空文档文本 maxMessageSize == 0
  • 空文档文本 maxMessageSize > 0
  • 非空的文档文本 maxMessageSize == text.length()
  • 非空的文档文本 maxMessageSize > text.length()
  • 非空的文档文本maxMessageSize < text.length()addHighlight()投掷BadLocationException

笔记

  1. 感知BadLocationException它有点棘手,因为它产生的是stdout的输出; 幸运的是,您可以通过System.setOut轻松地重新分配stdout .但是,您可能需要考虑改进异常处理,至少使用日志框架而不是打印到stdout.
  2. 从代码看来,似乎其他方法(例如removeAllHighlights()和/或getText())也可以抛出BadLocationException,但是try-catch块没有很好地组织.我会考虑在这些方法抛出时添加更多单元测试,然后重构异常处理代码.

更新

我以为我做的事情有问题...请你提供修改/更正的代码吗?

您的testSetLength方法并不是真正测试任何东西 - 您需要断言语句(和/或EasyMock验证),以便您的单元测试能够实际验证某些行为.但是,它提供了设置测试类的缺失线索.所以我尝试统一你的两个测试方法来创建一个有希望工作的方法(我是从内存写的,所以我不能保证它会在第一次尝试时完全编译和运行):

  @Test 
  public void testEmptyText() { 
    // set up the test class with a specific max length
    classUnderTest = new MaxLength(125); 
    // this shall be called from inside decorate()
    mockDocument.addDocumentListener(classUnderTest); 
    // the mock document shall always return an empty text
    EasyMock.expect(mockDocument.getText(0, 1)).andStubReturn(""); 
    // we expect this to be called from inside handle()
    mockHighlighter.removeAllHighlights();
    // start replay mode
    EasyMock.replay(mockComponent, mockEvent, mockDocument, mockHighlighter); 
    // inject mock component into tested object
    maxListener.decorate(mockComponent); 

    // call the tested method
    classUnderTest.handle(mockEvent); 

    // verify that all expected calls to the mocks have been made    
    EasyMock.verify(mockComponent, mockEvent, mockDocument, mockHighlighter); 
  }
Run Code Online (Sandbox Code Playgroud)