0

Please take a look at my scenario below,

public class Test
{
    private Tech tech = null;

    ...

    public Tech GetExpectedTech(string condition)
    {
        ...

        return tech;
    }
}

I'm not sure the best way to do unit test this method. Maybe I can use reflection, but I don't think this is a sensible way. Anybody has ideas?

forsvarir
  • 10,749
  • 6
  • 46
  • 77
Allen4Tech
  • 2,094
  • 3
  • 26
  • 66
  • I suggest reading [this](http://stackoverflow.com/questions/1093020/unit-testing-and-checking-private-variable-value) – Yuval Itzchakov Jul 08 '15 at 07:20
  • For purists, unit testing tests behavior and not code/implementation. So whatever you do in your method and how you do it is not important in unit testing. It is what the method do and behave depending on your expectations. So you shouldn't care about private elements. If the inner implementation change but the method still behave like before, your test(s) shouldn't break. – JoeBilly Jul 08 '15 at 07:59

1 Answers1

0

Think about what it is you're actually interested in testing. For your GetExpectedTech method, you're passing in a string and returning a Tech. presumably there is some connection between the string passed in and the Tech returned. That's what you should be testing (not null probably, contains expected values etc).

If a side effect of the method is that the Tech is stored in a field of the class, then you must be doing it for a reason (if not you shouldn't be doing it). Currently there's no reason in the code you've posted, however the most likely reason would seem to be that there will be other methods in the class that use that Tech or return it. At the point you can link the two methods up to create a relationship between the two methods. There's nothing wrong with calling multiple methods on your SUT if the relationship between the methods is part of what you're trying to test, so you could do:

var expectedTech = sut.GetExpectedTech(someString);
var otherTech = sut.DoSomethingElse(someOtherParams);
Assert.AreEqual(expectedTech, otherTech);

If it's interactions with the Tech that you need to test for other methods, then you may need to look at creation patterns so that you're able to inject a Mock into your SUT, but without knowing what else your class does it's hard to say if this would be necessary or not.

As you've said, you can access the member using reflection, or PrivateObject however the number of scenarios where this is the right thing to do are relatively small, so if you need to do that, it could be a sign that your class needs refactored.

Community
  • 1
  • 1
forsvarir
  • 10,749
  • 6
  • 46
  • 77
  • thanks for your kindly reply. Actually, this is a request builder class, the parameter is a requestType enum, and this class only implements a request builder interface. No other method in this class. – Allen4Tech Jul 08 '15 at 07:57
  • @AllenLi-AI3 Then is sounds like your test might be that if you call the method twice you get the same instance of `Tech` back. Otherwise, I'm not sure why you're updating the member variable. – forsvarir Jul 08 '15 at 08:08
  • this is not for updating member variable, this is creating a request based on the requestType parameter and return it. – Allen4Tech Jul 08 '15 at 08:14
  • @AllenLi-AI3 Then why are you storing it in the class and not simply returning it? – forsvarir Jul 08 '15 at 08:25
  • What I want to test is if the method return me a correct request, so I think I should be check each properties in the returned instance. Storing it in class or not is not the problem, create the instance in method is also ok. – Allen4Tech Jul 08 '15 at 08:38
  • @AllenLi-AI3 then yes, you should be checking that the returned value isn't null and that public properties on that returned instance have the expected values. – forsvarir Jul 08 '15 at 08:43