Unit Testing a Method With No Return Value

Unit testing a class with no return value?

What you're describing is often called behavior verification (as opposed to state verification). It's got its proponents and detractors, but for several categories of classes it's the only game in town if you want to unit test.

To unit test a class whose behavior is limited to interacting with collaborators, you typically pass mock collaborator objects that are instrumented in a way that allows you to verify their methods have been called in the way you expect.

If you were to do this by hand (yuck!) for the classes you mentioned in your question, you might create a MockParser class that implements IParser and adds properties that record if and how its methods were called.

It's better to use mocking framework that will create the mocks on the fly, specify expections on them, and verify those expectations.

I've been using NMock2 these days, and the tests look something like this:

// 'mockery' is the central framework object and Mock object factory
IParser mockParser = mockery.NewMock<IParser>();

// Other dependencies omitted
Job job = new Job(mockParser);

// This just ensures this method is called so the return value doesn't matter
Expect.Once.On(mockParser).
.Method("Parse").
.WithAnyArguments().
.Will(Return.Value(new object()));

job.Run();
mockery.VerifyAllExpectationsHaveBeenMet();

Write a Unit Test for function without return value

I don't think it is very clean, but this would work:
I made a new file to separate the production code from the testing code.
I imported the list (in my code it's l) and test on it.
My main.py:

from typing import Any

l = []

def myfunc(link: Any) -> None:
my_actual_value = "my_expected_value"
l.append(my_actual_value)

My main_test.py:

import unittest

import main
from main import myfunc

class TestMyFunc(unittest.TestCase):
def setUp(self) -> None:
main.l = []

def test_my_func(self) -> None:
# Given
some_link = "some_link"
my_expected_value = ["my_expected_value"]
# When
myfunc(some_link)
# Then
assert my_expected_value == main.l

def test_my_func2(self) -> None:
# Given
some_link = "some_link2"
my_expected_value = ["my_expected_value"]
# When
myfunc(some_link2)
# Then
assert my_expected_value == main.l

How to unit test a method with no return value but which writes to System.out

As it stands, you would need a tool like PowerMock to mock System.out in order to determine what the method tried to print. How about breaking up the concerns of working out the message (which needs to be tested) and the concern of display.

public String determineMessage() {
String msg = "Forecast Display: ";
if (currentPressure > lastPressure) {
msg += "Improving weather on the way!";
} else if (currentPressure == lastPressure) {
msg += "More of the same";
} else if (currentPressure < lastPressure) {
msg += "Watch out for cooler, rainy weather";
return msg;
}

public void display() {
System.out.println(determineMessage());
}

This way unit testing can be done by setting various pressures on the class and asserting that the message is determined correctly.

How does one test a function that has no return value?

Static state methods naturally make themselves fairly untestable, so my suggestion is based around refactoring your code away from static methods.

I would turn Logger into an instance class that takes an IO object in the constructor. That will allow you to stub the IO object and you can Assert that your IO object's Close method was called.

This is only if you want to make your code 100% testable. Otherwise, I would agree with Mo that if it is not testable, then do not write a forced test...those tend to be very brittle. In the end, you need to be pragmatic about your code. Often a logger is useful to keep static, however as I already mentioned, these tend to be very untestable....so just be pragmatic about your work and don't write tests in the mere effort to get 100% code coverage...that 100% will come with a price...

UPDATE

Here is why this is not truly testable from a dogmatic POV of unit testing. You are not testing a unit of work, but instead you are testing the Logger AND the Logger's dependencies (the IO object in this case). It also makes your tests slower and requiring environmental setup and state (you must have first opened an actual file to close it, right?). These are all bad for unit testing, but ok for integration testing...so it depends on what kind of tests you are writing, also.

Unit testing a method with no return value

rss_file can take either a file name or a file-like object as its argument. Rewrite generate_feed to accept an argument that gets passed to rss_file.

def generate_feed(file_list, fobj="podcast.xml"):
fg = FeedGenetaror()
for f in file_list:
fe = fg.add_entry()
fg.rss_str(pretty=True)
fg.rss_file(fobj)

In production, you can write

with open("podcast.xml", "w") as f:
generate_feed(file_list, f)

or simply

generate_feed(file_list)

For testing, you can use a StringIO object.

f = io.StringIO()
generate_feed(file_list, f)

Then you can test the contents of f (via f.getvalue()) as if it were the XML file you generated.

In python, how to do unit test on a function without return value?

In this particular case, I would mock print, then then use the mock in my assertion.

In Python, you will use the Mock package to mock.

How to use Moq to test a method with no return value?

The simple answer is, you can't. The method that UpdateAllItems calls (Increment()) is non-virtual, so you won't be able to mock it.

Your options, as I see it, are:

  • Don't test UpdateAllItems at all. Its implementation is trivial, so this is an option to consider (though not ideal).
  • Create real SingleItem_CodeCantBeModified instances in your test. Purists would say that you no longer have a unit test at this point, but it could still be a useful test.
  • Add an ISingleItem interface, and an SingleItemAdapter : ISingleItem class that holds onto a reference to a SingleItem_CodeCantBeModified and forwards the calls. Then you can write SingleItemManager to operate on ISingleItems, and you'll be free to pass in mock ISingleItems in your tests. (Depending on how your system is set up, you might even be able to descend from SingleItem_CodeCantBeModified, implement the interface on your descendant, and use those objects instead of writing an adapter.)

That last option gives you the most options, but at the cost of some complexity. Choose the option that's best suited for what you're trying to accomplish.



Related Topics



Leave a reply



Submit