Unit Test a Method That Returns a Void

Unit testing void methods?

If a method doesn't return anything, it's either one of the following

  • imperative - You're either asking the object to do something to itself.. e.g change state (without expecting any confirmation.. its assumed that it will be done)
  • informational - just notifying someone that something happened (without expecting action or response) respectively.

Imperative methods - you can verify if the task was actually performed. Verify if state change actually took place. e.g.

void DeductFromBalance( dAmount ) 

can be tested by verifying if the balance post this message is indeed less than the initial value by dAmount

Informational methods - are rare as a member of the public interface of the object... hence not normally unit-tested. However if you must, You can verify if the handling to be done on a notification takes place. e.g.

void OnAccountDebit( dAmount )  // emails account holder with info

can be tested by verifying if the email is being sent

Post more details about your actual method and people will be able to answer better.

Update: Your method is doing 2 things. I'd actually split it into two methods that can now be independently tested.

string[] ExamineLogFileForX( string sFileName );
void InsertStringsIntoDatabase( string[] );

String[] can be easily verified by providing the first method with a dummy file and expected strings. The second one is slightly tricky.. you can either use a Mock (google or search stackoverflow on mocking frameworks) to mimic the DB or hit the actual DB and verify if the strings were inserted in the right location. Check this thread for some good books... I'd recomment Pragmatic Unit Testing if you're in a crunch.

In the code it would be used like

InsertStringsIntoDatabase( ExamineLogFileForX( "c:\OMG.log" ) );

Unit Test a method that returns a void

Since your method returns void, it probably has some side-effect that you can test/assert on.

In your case, an option would be to provide a mock instance of IDeviceAuthorisationRepositioryService. You can then check if a call to UpdatePhoneStatusToActive has happened. Here is a solution using Moq:

var mock = new Mock<IDeviceAuthorisationRepositioryService>();

var service = new DeviceAuthorisationService(mock.Object);
service.UpdateDeviceStatusToActive(....);

mock.Verify(x => service.UpdatePhoneStatusToActive(), Times.Never());

Unit testing save methods when return type is void

According to your comments you need to write an unit test for a save method. Try this example code,

@Autowired
private EmployeeDAO employeeDAO;

@Test
public void whenValidEmployee_thenShouldSave()
{
EmployeeEntity employee = new EmployeeEntity("1", "Department Name", "Role"); //id, department name and role are passing as constructor parameters
employeeDAO.save(employee);

List<EmployeeEntity> employees = employeeDAO.findAll();

//Assert
Assert.assertEquals(employee.getId(), employees.get(0).getId());
}

How to unit test a method which calls a void method?

You use the verify method:

verify(myRemovalService).removeData("Test1"));
verify(myRemovalService).removeData("Test2"));

How do i write unit test for function with void return type

This is the method that you intend to test, correct? I am surprised to see that it contains test code (configParser.parseConfig(TestHelper.getMockedJSONObject(fileLocation));)...

What exactly do you want to test?

  • You could for example verify the content of the file that gets written by loading that file. However, that accounts only for a part of the method logic.

  • I don't see any @Override annotation and therefore assume that you are not overriding a method. You could change the method signature to return the parsed config and check it with assertions.

  • There might be other ways to retrieve the configuration; this depends on the logic of configParser.parseConfig(...).

  • You could also consider extracting the last tree lines to another method and test that method.

To sum up, you can either change the method to return a result, or extract chunks to own methods and test these, or retrieve the result from another source (in case something like configParser.getParsedConfig() exists).

Can you unit test a void method which doesnt have return type?

Code properly refactored for testability

The proper way of coding and unit-testing such a logic would be:

public class SomeProductionClass 
{
public string findOccuranceMethod(string str)
{
string occurString = "o";
string replaceString = "MDDS";
var array = str.Split(new[] { occurString }, StringSplitOptions.None);
string result = string.Join(replaceString, array);

return result;
}
}

[TestMethod()]
public void findOccuranceMethodTest()
{
// Arrange
string expected = "The Haunting MDDSf Hill HMDDSuse!";
var productionClass = new SomeProductionClass();

// Act
var result = productionClass.findOccuranceMethod("The Haunting of Hill House!");

// Assert
Assert.AreEqual(expected, result);
}
How to test the original code

If for some reason you cannot control the production code, there are two options:

  • replace Console with an abstraction

  • reassign standard input/output to a custom stream: this is the least preferred option, as it makes setup/cleanup more complex, and can interfere with the test runner.

In either case, we must never modify the code under test in a way that would introduce separate branching for testing/production. E.g., "if running under test do A, otherwise do B" -- in such a case we aren't actually testing the production code but rather a different branch of it.

Replace Console with an abstraction

Here we introduce IConsole as a replacement for System.Console:

public interface IConsole
{
void WriteLine(string s);
void ReadLine(); // void is enough for this example
}

// for use in production
public class RealConsole : IConsole
{
public void WriteLine(string s)
{
Console.WriteLine(s);
}
public void ReadLine()
{
Console.ReadLine();
}
}

// for use in unit tests
public class TestConsole : IConsole
{
public void WriteLine(string s)
{
Contents.Add(s);
}
public void ReadLine()
{
}

public List<string> Contents { get; } = new List<string>();
}

The production code will remain as in the original post, except that now it consumes _console as a dependency:

public class SomeProductionClass
{
private readonly IConsole _console;

public SomeProductionClass(IConsole console)
{
_console = console;
}

public void findOccuranceMethod()
{
string str = "The Haunting of Hill House!";
_console.WriteLine("String: " + str);
string occurString = "o";
string replaceString = "MDDS";

var array = str.Split(new[] { occurString }, StringSplitOptions.None);
var count = array.Length - 1;
string result = string.Join(replaceString, array);

_console.WriteLine("String after replacing a character: " + result);
_console.WriteLine("Number of replaces made: " + count);
_console.ReadLine();
}
}

and the test code would be:

[TestMethod()]
public void findOccuranceMethodTest()
{
// Arrange
string expectedString = "The Haunting MDDSf Hill HMDDSuse!";
int expectedCount = 2;
var console = new TestConsole();
var productionClass = new SomeProductionClass(console);

// Act
productionClass.findOccuranceMethod();

// Assert
Assert.AreEqual(3, console.Contents.Count);
Assert.AreEqual("String: The Haunting of Hill House!", console.Contents[0]);
Assert.AreEqual(
$"String after replacing a character: {expectedString}",
console.Contents[1]);
Assert.AreEqual(
$"Number of replaces made: {expectedCount}",
console.Contents[2]);
}

Unit test for void methods C#

As already mentioned, unit tests usually target application logic public methods, not UI related methods.

If you really insist on testing your method, you should follow these steps:

1) Setup phase - this a phase to initialize the context of your tests. In you case initializing and opening of the form containing the combo boxes

2) Tear down phase - this is a phase to leave the things as if your tests never ran. E.g. close and dispose in your form

3) Actual test - get some combo boxes instances, have them enabled, call your method, check that all checkboxes are disabled

Some (pseudo-)-code using NUnit framework attributes (not tested, it is just to get you started):

[TestFixture]
public class YourFormTests
{
private Form frm;

[OneTimeSetUp]
public void SetUp()
{
frm = new Form();
frm.Show();
}

[OneTimeSetup]
public void TearDown()
{
frm?.Close();
frm?.Dispose();
}

[Test]
public void TestComboDisabled()
{
frm.cmbSomeName.Enabled = true;
frm.comboDisable();
Assert.IsFalse(frm.cmbSomeName.Enabled, "Combo is not disabled");
}
}

This assumes your method is public and also tested combo box. Theoretically, you can dynamically invoke a private method, but this is really ugly and not recommended (method rename produced a TargetInvocationException instead of compilation error).

This should provide a basic idea on the unit testing creation, but you should really read the basics.



Related Topics



Leave a reply



Submit