为Junit测试编写测试用例 [英] Writing test case for Junit testing

查看:199
本文介绍了为Junit测试编写测试用例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

作为开发人员,我是Unit测试的新手,并且要求写一个测试用例来单元测试以下代码。有人可以帮助我,还给我一些关于如何在日食中写单元测试的指针。

  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,画家);
} catch(BadLocationException ex){
System.out.println(ex.getMessage());
}
} else {
component.getHighlighter()。removeAllHighlights();
}
} catch(BadLocationException e1){
System.out.println(e1.getMessage());
}
}

谢谢






更新



由于某些原因,当我运行测试用例时,我没有得到任何覆盖所有。我在这里做错了吗?进一步的研究表明,我需要使用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;
私人荧光笔模拟器

@Before public void setUp(){
mockComponent = EasyMock.createMock(JTextComponent.class);
mockEvent = EasyMock.createMock(DocumentEvent.class);
mockDocument = EasyMock.createMock(Document.class);
EasyMock.expect(mockEvent.getDocument()).StandReturn(mockDocument);
EasyMock.expect(mockDocument.getLength())。和返回(256);
mockHighlighter = EasyMock.createMock(Highlighter.class);
EasyMock.expect(mockComponent.getHighlighter())。和返回(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);
}
}






要测试的类中存在 decorate(JtextComponent jComponent)方法( MaxLength ),并定义为: / p>

  public final void decorate(final JTextComponent c){
//如果已经装饰了
,则TODO抛出异常.component = c;
component.getDocument()。addDocumentListener(this);
}





更新:



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

但是现在我有一个不同的错误验证:

  java.lang.AssertionError:
验证失败:
getHighlighter():expected:1,actual:0
在org.easymock.internal.MocksControl.verify(MocksControl.java:184)
在org.easymock.EasyMock.verify(EasyMock。 java:2038)
at net.TestMaxLength.testEmptyText(TestMaxLength.java:98)

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

解决方案

我建议使用嘲笑框架,例如 EasyMock 。模拟器允许您使用所需的测试行为来配置依赖项。在您的情况下,您需要一个模拟 DocumentEvent ,理想情况下,另一个组件,我猜是一个类成员。



单元测试的两个方面




  • 如何
  • 要测试的 ,即验证的方案。



如何测试



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;
私人荧光笔模拟器

@Before
public void setUp(){
mockComponent = createMock(Component.class);
classUnderTest = new ClassUnderTest(mockComponent);
mockEvent = createMock(DocumentEvent.class);
mockDocument = createMock(Document.class);
expect(mockEvent.getDocument()).StringReturn(mockDocument);
expect(mockDocument.getLength())。andReturn(1);
mockHighlighter = createMock(Highlighter.class);
expect(mockComponent.getHighlighter())。和返回(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);
}

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



要测试的内容



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




  • 空文件文本与 maxMessageSize == 0

  • 空文档文本与 maxMessageSize> 0

  • 具有的非空文件文本maxMessageSize == text.length()

  • 非空文档文本, maxMessageSize> text.length()

  • 非空文档文本与 maxMessageSize< text.length() addHighlight() throwing BadLocationException



注意




  1. 感知 BadLocationException 有点棘手,因为它产生的都是stdout的输出;幸运的是,你可以通过 System.setOut 。但是,您可能希望考虑改进异常处理,至少通过使用日志框架而不是打印到stdout。

  2. 从代码看来,其他方法(如$ code> removeAllHighlights()和/或 getText())也可以抛出 BadLocationException 然而, try-catch 块的组织不是很好。我会考虑在这些方法抛出的情况下添加更多的单元测试,然后重构异常处理代码。



更新




我以为发生了错误,我在做...可以请你提供修改/更正的代码吗?


您的 testSetLength 方法没有真正测试任何内容 - 您需要assert语句(和/或EasyMock验证),以便您的单元测试实际验证一些行为。但是,它提供了设置测试类的缺失线索。所以我试图统一你的两个测试方法来创建一个有希望的工作(我正在从内存写入,所以我不能保证它将首先编译和运行完美):

  @Test 
public void testEmptyText(){
//设置具有特定最大长度的测试类
classUnderTest = new的MaxLength(125);
//这将从内部调用decorate()
mockDocument.addDocumentListener(classUnderTest);
//模拟文件总是返回一个空文本
EasyMock.expect(mockDocument.getText(0,1)).StringReturn();
//我们期望从内部调用handle()
mockHighlighter.removeAllHighlights();
//开始重播模式
EasyMock.replay(mockComponent,mockEvent,mockDocument,mockHighlighter);
//将mock组件注入测试对象
maxListener.decorate(mockComponent);

//调用测试方法
classUnderTest.handle(mockEvent);

//验证所有预期的对mocks的调用是否已经生成
EasyMock.verify(mockComponent,mockEvent,mockDocument,mockHighlighter);
}


As a developer, I'm a newbie to Unit testing and have a requirement to write a test case to unit test the following code. Could somebody help me here and also give me some pointers on how to write unit tests in 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()); 
    } 
} 

Thanks


Update

For some reason when I running the test case, I'm not getting any coverage at all. Am I doing something wrong here?? Further researching suggests that I need to use test.perform() method to call the method I want to test.. Is that correct?? Can you please suggest something?? Here is the code:

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


The decorate(JtextComponent jComponent) method is present in the class to be tested (MaxLength) and is defined as :

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

#

UPDATE:

@Peter: Managed to find out that it is not the Component class that is the problem but instead I needed asm (http://forge.ow2.org/projects/asm). I've also change the code to combine the 2 methods into 1 method:

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

But now I'm having a different error on verify:

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)

This is caused when executing EasyMock.verify() statement on mockComponent.

解决方案

I recommend using a mocking framework, such as EasyMock. Mocks allow you to configure dependencies with the desired behaviour for your tests. In your case, you need a mock DocumentEvent and ideally another one for component, which I guess is a class member.

The two aspects to unit testing

  • how to test, i.;e. the technical details of assembling the right set of objects in the right state required for the test to run properly (aka the _test fixture), and
  • what to test, i.e. the scenarios to validate.

How to test

Eclipse supports JUnit out of the box, so you may quickly generate new JUnit testcases (in Project Explorer context menu: New -> (Other ->) JUnit -> JUnit Test Case), then run it by clicking on the Run button.

Setting up the test fixture in your case would look something like this, using EasyMock (and assuming you can pass the component as a constructor parameter to your tested class):

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

This test assumes that maxMessageSize is at least 1 by default - setting maxMessageSize up for the test is left to you as an exercise as the code snippet you published gives no clue for that.

What to test

The method you show gets text from the document associated with the event, then based on its length, it does different things. I would write at least the following unit tests for this:

  • empty document text with maxMessageSize == 0
  • empty document text with maxMessageSize > 0
  • nonempty document text with maxMessageSize == text.length()
  • nonempty document text with maxMessageSize > text.length()
  • nonempty document text with maxMessageSize < text.length() and addHighlight() throwing BadLocationException

Notes

  1. sensing the BadLocationException is a bit tricky, since all it produces is an output to stdout; luckily, you can easily reassign stdout via System.setOut. However, you may want to consider improving exception handling, at least by using a logging framework instead of printing to stdout.
  2. from the code it seems that other methods (such as removeAllHighlights() and/or getText()) may also throw BadLocationException, however the try-catch blocks are not well organized. I would consider adding more unit tests where those methods throw, and after that, refactoring the exception handling code.

Update

I thought there was something wrong that I was doing...Can you please provide me with the modified/corrected code please???

Your testSetLength method is not really testing anything - you need assert statements (and/or EasyMock verification) in order for your unit tests to actually verify some behaviour. However, it provides the missing clue for setting up the tested class. So I try to unify your two test methods to create one which is hopefully working (I am writing from memory, so I can't guarantee it will all compile and run perfectly at first try) :

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

这篇关于为Junit测试编写测试用例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆