2

Recently, I started to use TDD. It's really cool and fun but creating expected object for assertEquals is very boring and tedious.

At the moment I see only two way for that:

Straightforward
Creating object in code using million of setters. Using that approach greater part of tests is creating expected object. I think it's not very cool.

Serialization
Writing expected object for example in JSON and then serialize it in test. I can't find disadvantages of that way except possibility of inconsistent state between my beans and test files.

EDIT

toString() (@Kilian Foth comment)
Some kind of serialization, but I think it deserves attention. Define a strictly controlled toString() and then assert equality with a literal string rather than a second object.

Configuring in DI container(inspired by @Spotted)
I remembered about DI. Does anybody configure expected bean in DI (Spring XML for example) and then inject it to test method? Is it bad and unefficient approach or something normal?

Are there any other techniques/approaches or special tools that can accelerate that process?

  • I do json serialisation to files when i want to compare exact output. Sometiimes i also get the test to output the actual object to a file as well. makes it easy to update the sample when things change – Ewan Oct 20 '15 at 12:10
  • 1
    This talk discuss about unit testing, object creation, DI, ... This may partially answer your question and help you to simplify your tests. – Spotted Oct 20 '15 at 12:33
2

Unless you are specifically testing the equals() method of a class, there is usually no reason for a unit test to assert the equality of two objects. A unit test should test one behaviour and not all features of a code unit, whether that is a module, a class or even a method (a method with many possible inputs usually needs many unit tests and not just one).

Therefore, there is often no need to create such a "comparison object". If you're verifying that a transaction puts your customer in the correct status, obtain the customer and assert things about its status, not that it's exactly equal to another complex object that the test provides. That is almost certainly testing too much an in a very brittle way, since any change to the customer class might break the "status" test.

|improve this answer|||||
  • I agree with you. But in my practice I often meet scenarios when I need to check complex transformation or genaration from template and other things like that. I think in these cases most simple and maybe one possible solution is to check equals of objects. Am I wrong? – Vladislav Koroteev Oct 20 '15 at 11:45
  • 1
    @vakoroteev If the entire purpose of an object is to represent the template for something, then yes, it can be useful to test all of its properties at once. In such cases I usually define a strictly controlled toString() and then assert equality with a literal string rather than a second object. – Kilian Foth Oct 20 '15 at 11:54
  • @KilianForth, ty. I added toString() way to question – Vladislav Koroteev Oct 20 '15 at 12:07
0

An other alternative I'd like to suggest is the following:

Instead of checking that the whole result object matches the expected value, write several asserts that check the important properties of the object.

Now, some people claim that you should only have 1 assert in a test. They are right that you should assert 1 thing, but that does not necessarily mean that you only have 1 assert.

Example: suppose you have a testcase that checks that after a bank transaction, some money moved. (Example in pseudo-code):

function testMoneyMovedAfterTransaction():
    account1 = setupFakeAccount(balance=300)
    account2 = setupFakeAccount(balance=600)
    performTransaction(from=account1, to=account2, amount=100)
    assertEquals(account1.balance, 200)
    assertEquals(account2.balance, 700)

See: two asserts, but I'm only asserting one thing: the money moved accounts, as requested.

Similarly, I might write a test for what happens when the balance is too low. That would be asserting that nothing happens to the balances, and you get an exception. That would take three asserts, but you're only asserting nothing changed.

Edit: if you're talking about 'templates' as in generated blobs of text: easiest might be to do a substring-search or regular-expression match against the generated text. For 'templates' as in generated data structures: an assert for individual fields might be the most robust.

|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.