3

Problem

Compiler gives me a warning at a return line with a message:

Unreachable code detected

Question

How can I refactor my unit test so I don't get compiler warning? Any other feedback is also welcome.

Code

I have a Bar class that wraps WCF calls. If exception happens somewhere inside a call, the wrapper would log an error and throw a WCF fault. Here is the class:

public class Bar
{
    private readonly ILog _execeptionLog;

    public Bar(ILog execeptionLog)
    {
        if (execeptionLog == null) 
            throw new ArgumentNullException("execeptionLog");

        _execeptionLog = execeptionLog;
    }

    public TResult TryExecute<TResult>(Func<TResult> action)
    {
        if (action == null) 
            throw new ArgumentNullException("action");

        try
        {
            return action.Invoke();
        }
        catch (Exception ex)
        {
            _execeptionLog.Error(ex.ToString());
            var fault = FooFault.CreateFrom(ex);
            throw new FaultException<FooFault>(fault);
        }
    }
}

I try to unit test this class to ensure that I get a fault with correct details. Here is my unit test method

[Test]
public void TryExecute_ActionThrowsException_FaultDetailIsNotNull()
{
    //Arrange
    var mock = MockRepository.GenerateMock<ILog>();
    var uut = new Bar(mock);
    var ex = new ArgumentException("foo");

    try
    {
        //Act
        int actual = uut.TryExecute(() =>
        {
            throw ex;
            return 1; //<<<<<<<< Unrechable code detected here
        });
    }
    catch (FaultException<FooFault> fault)
    {
        //Assert
        Assert.IsNotNull(fault.Detail);
    }
}
Community
  • 1
  • 1
oleksii
  • 35,458
  • 16
  • 93
  • 163
  • How do you expect to both throw an exception and return a valid value? – sq33G May 01 '13 at 11:30
  • I don't. I am trying to test that a WCF fault gets generated. I thought a return statement needs to be there to make the code compile, as the `Bar.TryExecute` returns a `TResult`. – oleksii May 01 '13 at 11:33
  • Try without it and see what happens. – sq33G May 01 '13 at 11:34
  • an example of this is when VS scaffolds `throw new NotImplementedException();` when you use it to implement an interface – paul May 01 '13 at 11:35
  • throw ex; sends you straight to catch. It will skip over everything else, making it unreachable. Only solution I can think of is to stick "return 1;" in the catch – Steven Mills May 01 '13 at 11:37
  • `Func r = () => { throw new Exception(); };` compiles fine for me – sq33G May 01 '13 at 11:42
  • @sq33G If I change this line `int actual = uut.TryExecute(() =>` to `int actual = uut.TryExecute(() =>` and remove the `return` it compiles w/o warnings. Thanks for the help. – oleksii May 01 '13 at 11:48

1 Answers1

2

You could do this...

int actual = uut.TryExecute<int>(() =>
{
    throw ex;
    // return 1; //<<<<<<<< Unrechable code detected here
});

And this is full...

var uut = new Bar(null);
var ex = new ArgumentException("foo");
try
{
    int actual = uut.TryExecute<int>(() =>
    {
        throw ex;
    });
}
catch (Exception fault)
{
    Assert.IsNotNull(fault.Message);
}
NSGaga-mostly-inactive
  • 14,052
  • 3
  • 41
  • 51