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 testabilityThe 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 codeIf for some reason you cannot control the production code, there are two options:
replace
Console
with an abstractionreassign 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
Where Are the Properties.Settings.Default Stored
How to Open in Default Browser in C#
How to Use Task.Delay as a Timer
Getting Error Message Box When Textbox1.Text Is Empty
Lambda Where Id Does Not Exist in Another List
Returning a File to View/Download in ASP.NET MVC
How to Ignore First Two Columns of CSV File
C# File.Delete, File Being Used by Another Process
Best Way to Check If a Data Table Has a Null Value in It
How to Modify a Getter and Setter, to Handle a Null Reference Exception
Multidimensional Array from a Txt File
How to Correctly Write Parallel.For With Async Methods
Use Latest Version of Internet Explorer in the Webbrowser Control
How to Add Double Quotes to a String That Is Inside a Variable
Fetching Value from a Datatable into Datatable With Where Clause