为 Junit 测试编写测试用例
作为一名开发人员,我是单元测试的新手,需要编写一个测试用例来对以下代码进行单元测试。有人可以在这里帮助我,并给我一些关于如何在 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());
}
}
谢谢
更新
由于某种原因,当我运行测试用例时,我根本没有得到任何覆盖。我在这里做错了什么吗?进一步的研究表明我需要使用 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);
}
}
decorate(JtextComponent jComponent)
方法存在于要测试的类 (MaxLength
) 中,并定义为:
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发现问题不是 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:
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)
这是在执行 EasyMock.verify 时引起的mockComponent 上的 () 语句。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我建议使用模拟框架,例如EasyMock。模拟允许您使用测试所需的行为来配置依赖项。在您的情况下,您需要一个模拟
DocumentEvent
,理想情况下还需要另一个用于component
的模拟,我猜它是一个类成员。单元测试如何测试的两个方面
如何测试
Eclipse 支持开箱即用的 JUnit,因此您可以快速生成新的 JUnit 测试用例(在 Project Explorer 上下文菜单中:New -> (Other ->) JUnit -> JUnit Test Case),然后通过单击运行它在运行按钮上。
使用 EasyMock 在您的案例中设置测试装置看起来像这样(并假设您可以将组件作为构造函数参数传递给测试的类):
此测试假设
maxMessageSize
至少为 1默认情况下 - 为测试设置maxMessageSize
留给您作为练习,因为您发布的代码片段没有提供任何线索。测试内容
您展示的方法从与事件关联的文档中获取文本,然后根据其长度执行不同的操作。我至少会为此编写以下单元测试:
maxMessageSize == 0
的空文档文本maxMessageSize > 的空文档文本0
maxMessageSize == text.length()
maxMessageSize > text.length()
maxMessageSize < text.length()
和addHighlight()
抛出BadLocationException
注意
BadLocationException
有点棘手,因为它产生的只是输出到标准输出;幸运的是,您可以通过 System.setOut。但是,您可能需要考虑改进异常处理,至少通过使用日志记录框架而不是打印到标准输出。removeAllHighlights()
和/或getText()
) 也可能抛出BadLocationException
,但是 < code>try-catch 块组织得不好。我会考虑在这些方法抛出的地方添加更多单元测试,然后重构异常处理代码。更新
您的 testSetLength 方法并未真正测试任何内容 - 您需要断言语句(和/或 EasyMock 验证)以便单元测试真正验证某些行为。然而,它为设置测试类提供了缺失的线索。因此,我尝试统一您的两种测试方法来创建一个有望正常工作的方法(我是从内存中编写的,所以我不能保证它在第一次尝试时就能完美编译和运行):
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 forcomponent
, which I guess is a class member.The two aspects to unit testing
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):
This test assumes that
maxMessageSize
is at least 1 by default - settingmaxMessageSize
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:
maxMessageSize == 0
maxMessageSize > 0
maxMessageSize == text.length()
maxMessageSize > text.length()
maxMessageSize < text.length()
andaddHighlight()
throwingBadLocationException
Notes
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.removeAllHighlights()
and/orgetText()
) may also throwBadLocationException
, however thetry-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
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) :当您编写单元测试时,您尝试测试(在本例中)该方法是否执行其应该执行的操作。您不应该查看实现并从中编写测试。相反,您应该考虑该方法应该能够处理哪些输入,以及调用该方法后应该产生什么结果(返回值和/或副作用)。
然后,您应该编写一个或多个测试,使用有效和无效的输入调用该方法,并使测试确认结果与您认为会发生的情况相符。
这是一个简短且不完整的描述,请在 Wikipedia 和 junit.org。
这是一个旧的(2005 年)但有效的指南 Eclipse 中的 JUnit。
When you write a unit test, you try to test if (in this case) the method does what it is supposed to do. You should not look at the implementation and write your test from that. Instead, you should think about what inputs the method should be able to handle, and what should be the result (returned value and/or side effects) after the method has been called.
Then you should write one or more tests that calls the method with valid and and invalid inputs and make the test confirm that the results matched what you thought would happen.
This was a short and incomplete description, read more at Wikipedia and junit.org.
Here is an old (2005) but working guide to JUnit in Eclipse.