1

I was trying to understand how to write unit tests for a few days now. I'm confused with following scenarios in the existing code.

In first function the max value changes depending on the object created at run time but in the second case it is a constant.

NOTE: The following functions are not related. These are two different scenarios.

SomeFunction1(arg1,....)
{
  if(arg1 > someObject.MaxAllowedValue)
  {
     throw exception;
  }
}
SomeFunction2(arg1,....)
{
  if(arg1 > maxAllowedValue)
  {
     throw exception;
  }
}

I am trying to test whether the function throws an exception when max value is exceeded.

Does the unit test remain the same in both the cases or is it different?

8
  • what is someObject? where it come from changes a lot of things in your code.
    – Yusubov
    Commented Aug 30, 2013 at 14:06
  • someObject is dynamically created and changes in each execution. To be more specific it is dependent on the hardware(which our software drives) connected to our system. Different hardware results in different someObject and thus a different MaxAllowedValue.
    – mssrivatsa
    Commented Aug 30, 2013 at 14:36
  • If someObject depends on the hardware, I'd follow DaveFar's advice and mock it.
    – Scroog1
    Commented Aug 30, 2013 at 14:41
  • How do you plan on controling all the values for each test? One test isn't going to account for all the possible values of someObject.MaxAllowedValue. You just need one that passess the test.
    – JeffO
    Commented Aug 30, 2013 at 14:49
  • @Scroog1 How does mock help? I can mock one object at a time. Let me put it with an example. Lets say my args1 value is 10. Different mock objects have different max values. Some more than 10 and some less. In that case when the actual code runs if condition execution depends on the object at that moment. How does my test ensure that?
    – mssrivatsa
    Commented Aug 30, 2013 at 15:09

2 Answers 2

1

That would depend somewhat on where someObject came from and how its property value changes. But assuming that someObject.MaxAllowedValue and maxAllowedValue have the same value, the test will remain the same. Remember, you are testing the behaviour of SomeFunctionX, not the implementation details.

2
  • No, both values are not same. Both functions are not even related code wise. Only relation between them is that they have same if condition. someObject.MaxAllowedValue depends on someObject and different for different executions of this function. Should the test be written for each different someObject in that case?
    – mssrivatsa
    Commented Aug 30, 2013 at 14:23
  • As Telastyn as said in another comment, you only need to test the two cases: exception should be thrown and exception shouldn't; it doesn't really matter which value of sameObject you choose to do it with.
    – Scroog1
    Commented Aug 30, 2013 at 14:59
1

TL;DR: 1) refactor your code 2) mock someObject

Refactor your code

Congraz, you are just unit testing for a few days now and have learned one of the most important aspects of unit testing (especially when done early in the development process):

The act of writing a unit test is more an act of design 
than of verification.  

(Uncle Bob, Agile Software Development, Principles, Patterns, and Practices)

So if SomeFunction1 and SomeFunction2 have closely related functionality and concerns, refactor them into one method. If not, you also need to write different unit tests for them since they cover different functionality/concerns.

Mock

If your code still contains

if(arg1 > someObject.MaxAllowedValue)

think about whether your current unit test should also test someObjects (probably not). If not, you should mock it, e.g. with EasyMock (this cheat sheet is helpful for both junit and EasyMock).

Update: Since you are testing another class, not that of someObject, it does not matter that someObject changes at runtime. All you have to do is cover all possible behaviors of your implementation under test with your tests, e.g.

  • arg1 == someObject.MaxAllowedValue
  • arg1 == someObject.MaxAllowedValue+1
4
  • Thanks for your reply. I should have been clear because the two functions are not related. So refactor doesn't apply. Second, I am mocking the object. But object differs from execution to execution. In such cases how should a test be written?
    – mssrivatsa
    Commented Aug 30, 2013 at 14:44
  • 2
    @mssrivatsa - You should test the rule "if more than max, throw" (and also that less than or equal to does not throw). It doesn't matter how the max is created, the test should control that and verify the rule.
    – Telastyn
    Commented Aug 30, 2013 at 14:49
  • @Telastyn Ok, so that should be the only check by the unit test, whether there is exception or not irrespective of how data is created?
    – mssrivatsa
    Commented Aug 30, 2013 at 15:16
  • exactly, mssrivatsa. I updated my answer.
    – DaveFar
    Commented Aug 30, 2013 at 18:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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