Describe the solution you'd like
Currently, Rocks supports throwing an exception from a mocked member through the Callback() method. While this works, it can be a little confusing and clumsy, especially if the member has parameters:
expectations.Setups.Target(…bunch of Args…)
.Callback((_, _, _, _) => throw new NotSupportedException());
If there was a Throws(), it could make it bit simpler:
expectations.Setups.Target(…bunch of Args…)
.Throws<NotSupportedException>();
There would be two overloads:
public Adornments<…> Throws<TException>() where TException : Exception, new()
public Adornments<…> Throws<TException>(TException exception) where TException : Exception
The first one is used if the user is fine with the no-argument constructor being called to make the new exception. The second one is used if the user needs to provide more information to the exception. In either case, these would set a public Exception? Exception { get; private set; } on the handler. This would be used to determine if it should be thrown when the member is invoked.
Note that the second overload may need to be a Func<TException> because we want the call stack in both cases to come from the invocation of the mocked member, not from where the adornment is made. I need to check to see if the exception is made is irrelevant from where it’s thrown. I’m pretty sure it doesn’t matter, so letting the user specify the exception instance in Throws() should be fine.
I’d also add to documentation the precedence when the mocked member is called.
• If Throws() was called, this exception is thrown
• Else, if Callback() was called, this is invoked.
• Else, if the method returns a value, ReturnValue() is called.
Describe alternatives you've considered
Keep using Callback()
Describe the solution you'd like
Currently, Rocks supports throwing an exception from a mocked member through the
Callback()method. While this works, it can be a little confusing and clumsy, especially if the member has parameters:If there was a
Throws(), it could make it bit simpler:There would be two overloads:
The first one is used if the user is fine with the no-argument constructor being called to make the new exception. The second one is used if the user needs to provide more information to the exception. In either case, these would set a
public Exception? Exception { get; private set; }on the handler. This would be used to determine if it should be thrown when the member is invoked.Note that the second overload may need to be a
Func<TException>because we want the call stack in both cases to come from the invocation of the mocked member, not from where the adornment is made. I need to check to see if the exception is made is irrelevant from where it’s thrown. I’m pretty sure it doesn’t matter, so letting the user specify the exception instance inThrows()should be fine.I’d also add to documentation the precedence when the mocked member is called.
• If
Throws()was called, this exception is thrown• Else, if
Callback()was called, this is invoked.• Else, if the method returns a value,
ReturnValue()is called.Describe alternatives you've considered
Keep using
Callback()