Java 实例变量的 Setter 和 Getter 的 Junit 测试
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21354311/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Junit Test of Setters and Getters of Instance Variables
提问by user3126529
When creating test cases for setters and getters of instance variables within the object. What is the best approach? Here I use the get and set methods within my tests. Would this be poor testing strategy?
为对象内的实例变量的 setter 和 getter 创建测试用例时。最好的方法是什么?在这里,我在测试中使用了 get 和 set 方法。这会是糟糕的测试策略吗?
/**
* Test of setFlightNumber method, of class Flight.
*/
@Test
public void testSetFlightNumber() {
System.out.println("setFlightNumber");
int flightNumber = 1000;
Flight instance = new Flight();
instance.setFlightNumber(flightNumber);
// TODO review the generated test code and remove the default call to fail.
assertEquals(instance.getFlightNumber(), flightNumber);
}
/**
* Test of getFlightNumber method, of class Flight.
*/
@Test
public void testGetFlightNumber() {
System.out.println("getFlightNumber");
Flight instance = new Flight();
int expResult = 1000;
instance.setFlightNumber(1000);
int result = instance.getFlightNumber();
assertEquals(expResult, result);
}
回答by Makoto
The main principle of unit testing is that you test a simple unitof code; that is, each method should be tested on its own merits.
单元测试的主要原则是测试一个简单的代码单元;也就是说,每种方法都应根据其自身的优点进行测试。
This means we can't use the get
method in our set
test, and vice versa - you're not testing the individual unit of code that is the single method.
这意味着我们不能get
在set
测试中使用该方法,反之亦然 - 您不是在测试作为单个方法的单个代码单元。
Given that...
鉴于...
Let's say we have a PlainOldJavaObject
with a field value
that we want (for some reason) to test the validity of setters and getters for. The only appropriate way to do this is through the use of reflection.
假设我们有一个PlainOldJavaObject
字段value
,我们想要(出于某种原因)测试 setter 和 getter 的有效性。唯一合适的方法是使用反射。
Here's my class declaration, which is pretty skinny:
这是我的类声明,它非常简单:
public class PlainOldJavaObject {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
I now set up my test class to make use of reflection; specifically using the Field
class:
我现在设置我的测试类来使用反射;具体使用Field
该类:
public class PlainOldJavaObjectTest {
@Test
public void testSetter_setsProperly() throws NoSuchFieldException, IllegalAccessException {
//given
final PlainOldJavaObject pojo = new PlainOldJavaObject();
//when
pojo.setValue("foo");
//then
final Field field = pojo.getClass().getDeclaredField("value");
field.setAccessible(true);
assertEquals("Fields didn't match", field.get(pojo), "foo");
}
@Test
public void testGetter_getsValue() throws NoSuchFieldException, IllegalAccessException {
//given
final PlainOldJavaObject pojo = new PlainOldJavaObject();
final Field field = pojo.getClass().getDeclaredField("value");
field.setAccessible(true);
field.set(pojo, "magic_values");
//when
final String result = pojo.getValue();
//then
assertEquals("field wasn't retrieved properly", result, "magic_values");
}
}
In the first test, I am making certain that the field is read by reflectively accessing the value contained in the field for the instance of PlainOldJavaObject
. Without violating the integrity of the declared class*, I am confident that the field is being set appropriately.
在第一个测试中,我通过反射访问PlainOldJavaObject
. 在不违反声明的类 * 的完整性的情况下,我相信该字段设置得当。
In the second test, I assume that the value has already been set to something prior, so the set-up involves populating the field with a known default value. When I read the value back, I am asserting that the value read back is the value that we know it was originally set to.
在第二个测试中,我假设该值已经设置为之前的某个值,因此设置涉及使用已知的默认值填充该字段。当我读回值时,我断言读回的值是我们知道它最初设置的值。
Ultimately, if you have a lot of setters and getters, you'll have to do code like this (since, if you rely on the assumption that your setters and getters "just work", like you are in your tests above, your test cases maybe invalid).
最终,如果你有很多 setter 和 getter,你将不得不做这样的代码(因为,如果你依赖于你的 setter 和 getter“正常工作”的假设,就像你在上面的测试中一样,你的测试情况可能无效)。
*: Mind you, reflection is a quick and fast way to get into extreme trouble with undefined behavior, and you have few guarantees of object immutability. You're taking the shrink wrap off of the language and are doing strange and unusual things. Proceed at your own peril.
*:请注意,反射是在未定义行为中陷入极端麻烦的一种快速而快速的方法,并且您几乎无法保证对象的不变性。你正在撕掉语言的包装纸,做一些奇怪和不寻常的事情。继续操作,后果自负。
回答by John B
I believe that getter / setter testing does have value in that it could catch typo errors. However very little time should be spent on them since these errors are not frequent due to code generation tools. Hence using a tool to execute these test rather than writing them yourself is good practice.
我相信 getter/setter 测试确实有价值,因为它可以捕获拼写错误。然而,由于代码生成工具,这些错误并不常见,因此应该花很少的时间在它们上面。因此,使用工具来执行这些测试而不是自己编写它们是一种很好的做法。
There exist a library to help: OpenPojo
有一个库可以提供帮助:OpenPojo
Couple other notes...
其他一些注意事项...
- There is no need to use two test methods. Use one since it will exersize both the getter and setter.
- Consider using a
Theory
to test a range of valid values (0, 1, Integer.MAX_VALUE
). You might also use TestedOnto pass those int in-line example here - Test error conditions like passing
-1
回答by user6123723
This will automatically test all the getters and setters making sure that the values are properly set.
这将自动测试所有 getter 和 setter,确保正确设置值。
testBean
public void testBean(java.lang.Object bean)
throws java.lang.Exception
Test the properties that have both getters and setters. Exclude those who have been excluded by excludeProperty(String). If the object implements Serializable, do a check to ensure it really is.
Parameters:
bean - the object to test
Throws:
java.lang.Exception - on failure
回答by Austin_Anderson
the problem is that you have no way of knowing in either test whether the issue is in your getter or is in your setter, since you have to use one to test the other. you can either
问题是您无法在任一测试中知道问题是在您的 getter 中还是在您的 setter 中,因为您必须使用一个来测试另一个。你可以
use reflection
mark your private field as protected and have your test inherit from the target,
or don't test getters and setters
使用反射
将您的私有字段标记为受保护,并让您的测试从目标继承,
或者不要测试 getter 和 setter
I'm still not experienced enough to tell what the best one is, but I know they all have drawbacks.
我仍然没有足够的经验来判断什么是最好的,但我知道它们都有缺点。
回答by Rishab Manocha
I think the approach used to test the getters and setter is perfectly valid and IMHO, I think that's how getter-setters should be tested.
我认为用于测试 getter 和 setter 的方法是完全有效的,恕我直言,我认为应该如何测试 getter-setter。
A common statement I hear is that unit test should test only a unit, therefore, a single method of a class. However, in that case we are better off calling it single-method-testing. A unit, if possible, should be a method, but more than that it is a use-case!
我听到的一个常见说法是单元测试应该只测试一个单元,因此,一个类的单个方法。但是,在这种情况下,我们最好将其称为单方法测试。如果可能,一个单元应该是一个方法,但更重要的是它是一个用例!
Consider a class like this
考虑这样一个类
public class PlainObject {
void setA(int a) {
}
}
In this if you write any unit test that calls the method, it will pass because this method does nothing. And that is perfectly valid because calling this method is the only possible use case. It doesn't affect the behaviour of the application is any way.
在这种情况下,如果您编写任何调用该方法的单元测试,它将通过,因为该方法什么都不做。这是完全有效的,因为调用此方法是唯一可能的用例。它不会以任何方式影响应用程序的行为。
It is correct to make one test that use both getters and setters because by itself you can't test the behaviour of the setter method. Moreover, the behaviour of setter doesn't even matter until you perform a get. If all I do it is call a setter and never get that value or use in any other way, there is no point of having a setter.
进行一个同时使用 getter 和 setter 的测试是正确的,因为您无法单独测试 setter 方法的行为。此外,在执行 get 之前,setter 的行为甚至无关紧要。如果我所做的只是调用一个 setter 并且永远不会获得该值或以任何其他方式使用,那么拥有一个 setter 就没有意义了。
Using reflections, or other fancy ways only tests the implementation. These methods don't test the behaviour of your code. In the end you end up writing your code as test which is useless.
使用反射或其他奇特的方式只能测试实现。这些方法不会测试您的代码的行为。最后,您最终将代码编写为无用的测试。
The only change I would make is change the name of the test method from testSetter to testAccess because you reading and updating the value.
我要做的唯一更改是将测试方法的名称从 testSetter 更改为 testAccess,因为您正在读取和更新该值。