The Author Online Book Forums are Moving

The Author Online Book Forums will soon redirect to Manning's liveBook and liveVideo. All book forum content will migrate to liveBook's discussion forum and all video forum content will migrate to liveVideo. Log in to liveBook or liveVideo with your Manning credentials to join the discussion!

Thank you for your engagement in the AoF over the years! We look forward to offering you a more enhanced forum experience.

shankbond (6) [Avatar] Offline
#1
Hi Roy,

First of all congratulation for giving this excellenat book on Unit Testing. I was actually struggling in my real life with unit testing.
I am facing a problem though:

public int DoSomething(int variable1, out string variable2, out float variable3)
{
...
}

given the above problem, how should I unit test this method as this method gives us three return values?

One way would be to:


public void DosSomethingTest(){
//add code for arrange
int expectedvalue=12;
string expectedVariable1="I am expected";
string expectedVariable3=15.9;
string actualVariable1, actualVariable3;
var sut=new Foo();
int actualValue=sut.DoSomething(15, out actualVariable1, out actualVariable3);

//this is where I am testing 3 concerns in one test. Is there a better way?
if(actualValue==expectedvalue){
if(expectedVariable1==actualVariable1){
if(expectedVariable3!=actualVariable3){
Assert.Fail("Unexpected variable2 returned");//pseudo code
}
}
else{
Assert.Fail("Unexpected variable1 returned");//pseudo code
}
}
else{
Assert.Fail("Unexpected Value returned");//pseudo code
}
}


but this test method violates that:

"You must not have any logic in Your asserts as this reduces readability of test, or I may be testing too many things at a time, hence creating brittle tests. "


Should I be wrtiting three different tests for these output parameters? Doesn't this violates DRY principle?


Thanks
shank
shankbond (6) [Avatar] Offline
#2
Re: How to unit test a method that has more that one output parameter?
Or Should I be using:

Seperate Test methods that tests concerns separately:

public void DosSomething_Passing15_Returns12Test(){
//add code for arrange
int expectedvalue=12;
string expectedVariable1="I am expected";
string expectedVariable3=15.9;
string actualVariable1, actualVariable3;
var sut=new Foo();
int actualValue=sut.DoSomething(15, out actualVariable1, out actualVariable3);

Assert.IsTrue(actualValue, expectedvalue);
}

public void DosSomething_Passing15_ReturnsExpectedVariable1Test(){
//add code for arrange
int expectedvalue=12;
string expectedVariable1="I am expected";
string expectedVariable3=15.9;
string actualVariable1, actualVariable3;
var sut=new Foo();
int actualValue=sut.DoSomething(15, out actualVariable1, out actualVariable3);

Assert.IsTrue(actualVariable1, expectedVariable1);
}

public void DosSomething_Passing15_ReturnsExpectedVariable2Test(){
//add code for arrange
int expectedvalue=12;
string expectedVariable1="I am expected";
string expectedVariable3=15.9;
string actualVariable1, actualVariable3;
var sut=new Foo();
int actualValue=sut.DoSomething(15, out actualVariable1, out actualVariable3);

Assert.IsTrue(actualVariable3, expectedVariable3);
}

Isn't approach 2 adhering to "Tests should not test more than one concern"?
241283 (1) [Avatar] Offline
#3
I think you should refactor your method.
Instead of using out parameters, create a class (or struct) that is the return value of the method.