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();

When you inject a mock, you pass to the Run class's constructor a test class that you will ask if the test passed. For example, you could test that the IParser mock got the correct request given the excel file you passed in the constructor. You can do this via your own class, and collect the results in it and test what it collected, or you could do this via a mocking framework that gives you ways of expressing such testing without constructing a class.

I see that you tagged your question with tdd, but in true tdd you don't really get this question (you do, but asked differently) because you build the test first, which defines the interface, instead of building the class interface and then thinking how are you going to test this thing. The need to test drives the design. You still use the same techniques (and likely end up with the same design in this case), but the question would have come out a bit different.