I'm new to AssertJ and using it to unit-test my written code and was thinking how to assert a list.
Lets assume we have a list of Consumers Entities. each Entity has it own Phone, own ServiceProvider which has it own Name and EntityName.
Now we want to assert that each Entity from a repository gets the right data, so we want to test that each item on list has equal Phone.
ConsumerEntity savedConsumer1 = Consumer(phone, name, serviceProvider)
List<ConsumerEntity> consumerListFromRepository = repository.findAllByPhone(phone)
Now I want to test that the data given from Repository is correct,
I can use this:
assertThat(consumerListFromRepository)
.extracting(ConsumerEntity::getPhone())
.containsOnly(savedConsumer1.getPhone());
Or I can do this with forEach (java 8):
consumerListFromRepository.forEach(consumerEntity ->
assertThat(consumerEntity.getPhone()).isEqualTo(savedConsumer1.getPhone()));
1. Which one is faster/simple-r/readable? I will go for the forEach for less lines of code but less read-ability as well.
2. Is there any other way to do it 1liner like the foreach but with asserThat? so it will be readable and simple - and without the need to use EqualTo each
time? something like:
asserThat(list).forEach........
3. Which one is faster? Extracting or forEach?
Thanks!
I'm not sure that "faster" is a primary concern here. It's likely that any performance difference is immaterial; either the underlying implementations are ~equivalent in terms of non-functionals or - since the context here is a unit test - the consumerListFromRepository is trivially small thereby limiting the scope for any material performance differences.
I think your main concerns here should be
Making it as easy as possible for other developers to:
Understand/reason about your test case
Edit/refactor your test case
Ensuring that your approach to asserting is consistent with other test cases in your code base
Judging which of your two approaches best ticks this box is somewhat subjective but I think the following considerations are relevant:
The Java 8 forEach construct is well understood and the isEqualTo matcher is explicit and easily understood
The AssertJ extracting helper paired with the containsOnly is less common that Java8's forEach construct but this pairing reads logically and is easily understood
So, IMHO both approaches are valid. If your code base consistently uses AssertJ then I'd suggest using the extracting helper paired with the containsOnly matcher for consistency. Otherwise, use whichever of them reads best to you :)
I write a lot of unit tests. Often, you need to write carefully considered test cases by hand, a form of whitebox testing. If you are lucky enough to work for a company with a separate quality assurance engineers, perhaps someone else writes test cases for you (kind of a mix between white and black box testing).
Many times, however, randomized testing would find many bugs and would serve as a great complement to hand-written cases.
For example, I might have a self-contained class and be able to express the invariants and broad-stroke behavior of the class simply (such as "this method never throws an exception" or "this method always returns a positive value"). I would like a test framework that just bashes on my class and checks the invariants.
A similar case: I often have a class which implements similar functionality to another class (but does it with different performance characteristics or with some added functionality). I would to A vs B test the two classes in a randomized way. For example, if I was implementing TreeMap, I could use HashMap as a comparable implementation (modulo a few differences due to the sorted behavior of TreeMap) and check most of the basic functionality in a randomized way. Simlarly, someone implementing LinkedList could use ArrayList as a comparable implementation and vice-versa.
I've written some basic stuff to do this in the past, but it is painstaking to set to up all the boilerplate to:
Create objects with random initial state
Apply random mutations
Create mappings between "like" objects for A vs B testing
Define invariants and rules such as "when will exceptions be thrown"
I still do it from time to time, but I want to reduce my effort level. For example, are there frameworks that remove or simplify the required boilerplate?
Otherwise, what techniques are used to do randomized testing in Java?
This is related, but not the same as fuzz testing. Fuzz testing seems to focus on random inputs to a single entity, in hope of triggering bad behavior, often with an adaptive input model based on dynamic coverage observations. That's covers a lot of the above, but doesn't cover, stuff like A vs B testing when comparable implementations exist, or invariant checking. In any case, I'm also interested in decent fuzz testing libraries for Java.
I think what you're trying to find is a library for Property Based Testing in Java (see types of randomized testing). Shortly: instead of testing the value of the result you're testing a property of it. E.g. instead of checking that 2+2 is 4 you're checking properties like:
random1 + 0 = random1
random1 + random2 >= random1
...
Take a look at this article that explains Property Based Testing in details.
Another option that you mention is to check with your Test Oracle - something that knows the true answer (e.g. old bullet-proof algorithm). So you pass a random variable both to old and new algorithm and you check that the results are equal.
Couple of Java libraries:
JUnit QuickCheck - a specialized lib for Property Based Testing. Allows you to define the properties and passes random values for these properties to check. So far (06/2016) it's pretty young, so you may want to check out ScalaCheck since it's possible to write Scala tests for Java code.
Datagen - random values generator for Java in case standard randomizers are not enough. Disclaimer: I'm the author.
I am currently debugging a rather complicated algorithm that fixes errors in a bit stream. A BitReader interface is quite simple, and the main reading method is like this:
/**
Reads bits from the stream.
#param length number of bits to read (<= 64)
#return read bits in the least significant bits
*/
long read(int length) throws IOException;
The objective is to test whether BitStreamFixer actually fixes the stream (in a way that is too hard to describe here). Basically I need to provide “broken” inputs to it and test whether its output is as correct as it can be (some inputs can't be fixed completely), like this:
BitStreamFixer fixer = new BitStreamFixer(input);
int word1 = fixer.readWord();
int word2 = fixer.readWord();
// possibly a loop here
assertEquals(VALID_WORD1, word1);
assertEquals(VALID_WORD2, word2);
// maybe a loop here too
Now, the BitStreamFixer class accepts an instance of BitReader. When unit testing the fixer, I obviously need one such instance. But where do I get one? I have two obvious options: either give it a real implementation of BitReader or mock it.
The former option is not really appealing because it would create a dependency on another object which has nothing to do with the class being tested. Moreover, it's not that easy because existing BitReader implementations read form input streams, so I'll need either a file or somehow prepared byte array, which is a tedious thing to do.
The latter option looks better and fits the usual unit testing approach. However, since I'm not even supposed to know what arguments the fixer will give to read, mocking it is not easy. I'll have to go with when(bitReader.read(anyInt())).thenAnswer(...) approach, implementing a custom answer that will create a lot of bit-fiddling logic to spoon-feed the object under test with proper bits in chunks of whatever size it asks for. Considering that bit streams I'm working with have rather complicated higher-level structure, it's not easy. And introducing logic in unit tests also doesn't smell good.
What do you think, is there any other option? Or maybe one of these can be improved in a way I fail to notice?
Write, test, and use a clear reusable test helper.
In a general sense, in unit testing, you're supposed to establish confidence in a system by watching it successfully interact with systems that you DO have confidence in. Of course you also want the system to be fast, deterministic, and easy to read/modify, but ultimately those come secondary to the assertion that your system work.
You've listed two options:
Use a mock BitReader, where you have enough confidence in predicting your system's interactions that you can set up the entire "when A then B" conversation. Mocking can be pretty easy when you have a small API surface of independent methods, like an RPC layer, but mocking can be very difficult when you have a stateful object with unpredictable method calls. Mocking is further useful to deterministically stub nondeterministic systems, like external servers or pseudorandom sources, or systems that don't exist yet; none of those is the case for you.
Because your read method can take a wide variety of parameters, each of which is valid and changes your system's state, then it's probably not a smart idea to use mocking here. Unless the order of calls that BitStreamFixer makes to BitReader is deterministic enough to make part of its contract, a mock BitReader will likely result in a brittle test: one that breaks when the implementation changes even if the system is perfectly functional. You'll want to avoid that.
Note that mocking should never yield "complicated logic", only complicated set-up. You're using mocks to avoid using real logic in your tests.
Use a real BitReader, which sounds like it will be painful and opaque to construct. This is probably the most realistic solution, though, especially if you've already finished writing and testing it.
You worry about "introducing new dependencies", but if your BitReader implementation exists and is fast, deterministic, and well-tested, then you shouldn't feel any worse about using it than using a real ArrayList or ByteArrayInputStream in your test. It sounds like the only real problem here is that creating the byte array would make it hard to maintain your test, which is a valid consideration.
In the comments, though, the real answer comes through: Build the BitWriter you're missing.
#Test public void shouldFixBrokenStream() {
BitReader bitReader = new StreamBitReader(BitWriter.create()
.pushBits(16, 0x8080)
.pushBits(12, 0x000) // invalid 12-bit sequence
.pushBits(16, 0x8080)
.asByteArrayInputStream());
BitStreamFixer fixer = new BitStreamFixer(bitReader);
assertEquals(0x80808080, fixer.read(32));
}
/** Of course, you could skip the BitReader yourself, and just make a new one. */
#Test public void shouldFixBrokenStream_bitReader() {
BitReader bitReader = new InMemoryBitReader();
bitReader.pushBits(16, 0x8080);
bitReader.pushBits(12, 0x000); // invalid 12-bit sequence
bitReader.pushBits(16, 0x8080);
BitStreamFixer fixer = new BitStreamFixer(bitReader);
assertEquals(0x80808080, fixer.read(32));
}
This is more readable than constructing an opaque bitstream offline and copy-pasting it into your test (particularly if well-commented), less brittle than mocks, and much more testable itself than an anonymous inner class (or Answer-based version of the same). It is also likely that you can use a system like that across multiple test cases, and possibly even multiple tests.
When designing test cases, I want to be able to use data that is random but static.
If I use data that is not random, then I will use trivial examples that are representative of the data I expect, rather than the data I have guarded against in my code. For example, if my code is expecting a string with a max length of 15 characters then I would rather specify these constraints and have the data generated for me, within those constraints, rather than some arbitrary example which may be, due to my expectations, within a more strict set of constraints.
If I use data that is not static, then my tests won't be repeatable. It is no good using a string that changes every time the test is run f the test then fails occasionally. It would be much better to use a consistent string and then specify more constraints upon how that string is generated (and obviously make the same checks in my code), if and when a bug is found.
Is this a good strategy for test data?
If so, then I know how to achieve both of these goals independently. For static, but non-random data I just enter something arbitrary e.g. foo. For something random but not static, I just use apache random utils e.g. randomString(5). How can I get both?
Note that when data must be unique, it would also be handy to have some way to specify that two pieces of generated data must be distinct. Randomness does this most of the time but cannot be relied upon, obviously, without having unreliable tests!
TL;DR: How can I specify the type of data I want to generate, without having randomised generated data?
Use a random with a constant seed. You can use the Random(long seed) constructor for it.
The RandomStringUtils.random() method can accept a Random source, which you could have created with a constant seed as described.
Using a constant seed is very useful for making experiments reproduceable - and using them is a very good practice, IMO.
don't do it. it gives you a headache, makes your tests unreadable and gives you no benefit. you already see the problems: specification of constraints. so let's go to the imaginary benefits. you worry about that manually you provide more constrained data then random data. but you want to use same data every time (same seed). so how do you know that random data are better than your manually provided data? how do you know that you chose seed properly? if you are not sure if your test data are good enough then:
simplify your code (extract methods/classes, avoid ifs, avoid nulls, be more immutable and functional)
look at edge cases and include them in your tests
look at generated data and check if some of them differs from what you were thinking of and add those data to your tests
use mutation testing
whenever a bug is discovered dufing development, uat or production, add those data to your tests
do truly random (not repetitive), long running tests. every generated data that breaks the tests should be logged and add to your deterministic unit tests.
by pretending to use random data you just lie to yourself. the data is not random, you don't control it and it makes you stop thinking about edge cases of your code. so don't do it, face the truth and make your tests readable and check more conditions
What you are describing is property based testing - the best known example being Haskell's quickcheck.
http://www.haskell.org/haskellwiki/Introduction_to_QuickCheck1
There have been a number of java ports such as
https://bitbucket.org/blob79/quickcheck
https://github.com/kjw/supercheck
https://github.com/pholser/junit-quickcheck
The Quickcheck philosophy emphasises the use of random data, but most (all?) of the java ports allow you to set a fixed seed so that the generated values are repeatable.
I've never got round to actually trying this approach, but I would hope it would make your tests more readable (rather than less readable as piotrek suggests), by separating the values from the tests.
If knowledge of the values is important to understand the test/SUT behavior then it is the wrong approach.
Instancio is a data generation library for unit tests that does what you are looking. E.g. if you need a random string of certain length:
Foo foo = Instancio.of(Foo.class)
.generate(field("fooString"), gen -> gen.string().length(10))
.create();
To generate a random predictable values, you can supply a seed:
Foo foo = Instancio.of(Foo.class)
.generate(field("fooString"), gen -> gen.string().length(10))
.withSeed(123)
.create();
Or if you use JUnit 5:
#ExtendWith(InstancioExtension.class)
class ExampleTest{
#Seed(1234)
#Test
void example {
Foo foo = Instancio.of(Foo.class)
.generate(field("fooString"), gen -> gen.string().length(10))
.create();
// ...
}
}
If you need predictable data always, you can configure a global seed value through a properties file. This way you won't need to specify it in the code.
https://github.com/instancio/instancio/
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
In the last weeks I've seen some guys using really long names for a Method or Class (50 characters), this is usually under the premise that it improves readability, my opinion is that a long name like this is an indicator that we are trying to do a lot or too much in a method class if we need such a long name, however I wanted to know what do you guys think about it.
An Example is:
getNumberOfSkinCareEligibleItemsWithinTransaction
A name in Java, or any other language, is too long when a shorter name exists that equally conveys the behavior of the method.
Some techniques for reducing the length of method names:
If your whole program, or class, or module is about 'skin care items' you can drop skin care. For example, if your class is called SkinCareUtils,
that brings you to getNumberOfEligibleItemsWithinTransaction
You can change within to in, getNumberOfEligibleItemsInTransaction
You can change Transaction to Tx, which gets you to getNumberOfEligibleItemsInTx.
Or if the method accepts a param of type Transaction you can drop the InTx altogether: getNumberOfEligibleItems
You change numberOf by count: getEligibleItemsCount
Now that is very reasonable. And it is 60% shorter.
Just for a change, a non-subjective answer: 65536 characters.
A.java:1: UTF8 representation for string "xxxxxxxxxxxxxxxxxxxx..." is too long
for the constant pool
;-)
I agree with everyone: method names should not be too long. I do want to add one exception though:
The names of JUnit test methods, however, can be long and should resemble sentences.
Why?
Because they are not called in other code.
Because they are used as test names.
Because they then can be written as sentences describing requirements. (For example, using AgileDox)
Example:
#Test
public void testDialogClosesDownWhenTheRedButtonIsPressedTwice() {
...
}
See "Behavior Driven Design" for more info on this idea.
Context "...WithinTransaction" should be obvious. That's what object-orientation is all about.
The method is part of a class. If the class doesn't mean "Transaction" -- and if it doesn't save you from having to say "WithinTransaction" all the time, then you've got problems.
Java has a culture of encouraging long names, perhaps because the IDEs come with good autocompletion.
This site says that the longest class name in the JRE is InternalFrameInternalFrameTitlePaneInternalFrameTitlePaneMaximizeButtonWindowNotFocusedState which is 92 chars long.
As for longest method name I have found this one supportsDataDefinitionAndDataManipulationTransactions, which is 52 characters.
Never use a long word when a diminutive one will do.
I don't think your thesis of "length of method name is proportional to length of method" really holds water.
Take the example you give: "getNumberOfSkinCareEligibleItemsWithinTransaction". That sounds to me like it does just one thing: it counts the number of items in a transaction that fall into a certain category. Of course I can't judge without seeing the actual code for the method, but that sounds like a good method to me.
On the other hand, I've seen lots of methods with very short and concise names that do way to much work, like "processSale" or the ever popular "doStuff".
I think it would be tough to give a hard-and-fast rule about method name length, but the goal should be: long enough to convey what the function does, short enough to be readable. In this example, I'd think "getSkinCareCount" would probably have been sufficient. The question is what you need to distinguish. If you have one function that counts skin-care-eligible items in transactions and another that counts skin-care-eligible items in something else, then "withinTransactions" adds value. But if it doesn't mean anything to talk about such items outside of a transaction, then there's no point cluttering up the name with such superfluous information.
Two, I think it's wildly unrealistic to suppose that a name of any manageable length will tell you exactly what the function does in all but the most trivial cases. A realistic goal is to make a name that gives a reader a clue, and that can be remembered later. Like, if I'm trying to find the code that calculates how much antimatter we need to consume to reach warp speed, if I look at function names and see "calibrateTransporter", "firePhasers", and "calcAntimatterBurn", it's pretty clear that the first two aren't it but the third one might be. If I check and find that that is indeed the one I'm looking for, it will be easy to remember that when I come back tomorrow to work on this problem some more. That's good enough.
Three, long names that are similar are more confusing than short names. If I have two functions called "calcSalesmanPay" and "calcGeekPay", I can make a good guess which is which at a quick glance. But if they are called "calculateMonthlyCheckAmountForSalesmanForExportToAccountingSystemAndReconciliation" and "calculateMonthlyCheckAmountForProgrammersForExportToAccountingSystemAndReconciliation", I have to study the names to see which is which. The extra information in the name is probably counter-productive in such cases. It turns a half-second think into a 30-second think.
I tend use the haiku rule for names:
Seven syllable class names
five for variables
seven for method and other names
These are rules of thumb for max names. I violate this only when it improves readability. Something like recalculateMortgageInterest(currentRate, quoteSet...) is better than recalculateMortgageInterestRate or recalculateMortgageInterestRateFromSet since the fact that it involves rates and a set of quotes should be pretty clear from the embedded docs like javadoc or the .NET equivalent.
NOTE: Not a real haiku, as it is 7-5-7 rather than 5-7-5. But I still prefer calling it haiku.
Design your interface the way you want it to be, and make the implementation match.
For example, maybe i'd write that as
getTransaction().getItems(SKIN_CARE).getEligible().size()
or with Java 8 streams:
getTransaction().getItems().stream()
.filter(item -> item.getType() == SKIN_CARE)
.filter(item -> item.isEligible())
.count();
My rule is as follows: if a name is so long that it has to appear on a line of its own, then it is too long. (In practice, this means I'm rarely above 20 characters.)
This is based upon research showing that the number of visible vertical lines of code positively correlates with coding speed/effectiveness. If class/method names start significantly hurting that, they're too long.
Add a comment where the method/class is declared and let the IDE take you there if you want a long description of what it's for.
The length of the method itself is probably a better indicator of whether it's doing too much, and even that only gives you a rough idea. You should strive for conciseness, but descriptiveness is more important. If you can't convey the same meaning in a shorter name, then the name itself is probably okay.
When you are going to write a method name next time , just think the bellow quote
"The man who is going to maintain your code is a phyco who knows where you stay"
That method name is definitely too long. My mind tends to wander when I am reading such sized method names. It's like reading a sentence without spaces.
Personally, I prefer as few words in methods as possible. You are helped if the package and class name can convey meaning. If the responsibility of the class is very concise, there is no need for a giant method name. I'm curious why "WithinTransaction" on there.
"getNumberOfSkinCareEligibleItemsWithinTransaction" could become:
com.mycompany.app.product.SkinCareQuery.getNumEligibleItems();
Then when in use, the method could look like "query.getNumEligibleItems()"
A variable name is too long when a shorter name will allow for better code readability over the entire program, or the important parts of the program.
If a longer name allows you to convey more information about a value. However, if a name is too long, it will clutter the code and reduce the ability to comprehend the rest of the code. This typically happens by causing line wraps and pushing other lines of code off the page.
The trick is determining which will offer better readability. If the variable is used often or several times in a short amount of space, it may be better to give it a short name and use a comment clarify. The reader can refer back to the comment easily. If the variable is used often throughout the program, often as a parameter or in other complicated operations, it may be best to trim down the name, or use acronyms as a reminder to the reader. They can always reference a comment by the variable declaration if they forget the meaning.
This is not an easy trade off to make, since you have to consider what the code reader is likely to be trying to comprehend, and also take into account how the code will change and grow over time. That's why naming things is hard.
Readability is why it's acceptable to use i as a loop counter instead of DescriptiveLoopCounterName. Because this is the most common use for a variable, you can spend the least amount of screen space explaining why it exists. The longer name is just going to waste time by making it harder to understand how you are testing the loop condition or indexing into an array.
On the other end of the spectrum, if a function or variable is used rarely as in a complex operation, such as being passed to a multi-parameter function call, you can afford to give it an overly descriptive name.
As with any other language: when it no longer describes the single action the function performs.
I'd say use a combination of the good answers and be reasonable.
Completely, clearly and readably describe what the method does.
If the method name seems too long--refactor the method to do less.
It's too long when the name of the method wraps onto another line and the call to the method is the only thing on the line and starts pretty close to the margin. You have to take into account the average size of the screen of the people who will be using it.
But! If the name seems too long then it probably is too long. The way to get around it is to write your code in such a way that you are within a context and the name is short but duplicated in other contexts. This is like when you can say "she" or "he" in English instead of someone's full name.
It's too long when it too verbosively explains what the thing is about.
For example, these names are functionally equivalent.
in Java: java.sql.SQLIntegrityConstraintViolationException
in Python/Django: django.db.IntegrityError
Ask yourself, in a SQL/db package, how many more types of integrity errors can you come up with? ;)
Hence db.IntegrityError is sufficient.
An identifier name is too long when it exceeds the length your Java compiler can handle.
There are two ways or points of view here: One is that it really doesn't matter how long the method name is, as long as it's as descriptive as possible to describe what the method is doing (Java best practices basic rule). On the other hand, I agree with the flybywire post. We should use our intelligence to try to reduce as much as possible the method name, but without reducing it's descriptiveness. Descriptiveness is more important :)
A name is too long if it:
Takes more than 1 second to read
Takes up more RAM than you allocate for your JVM
Is something absurdly named
If a shorter name makes perfect sense
If it wraps around in your IDE
Honestly the name only needs to convey its purpose to the the Developers that will utilize it as a public API method or have to maintain the code when you leave. Just remember KISS (keep it simple stupid)