C# 断言引发了已处理的异常
我正在处理几个异常,并且在处理之后不会重新抛出它们。C# 断言引发了已处理的异常,c#,nunit,moq,C#,Nunit,Moq,我正在处理几个异常,并且在处理之后不会重新抛出它们。 如何断言在单元测试中调用了异常。如果代码之外没有人会看到它,为什么要在意呢?我不会对这种不向调用方公开的功能进行单元测试。我要做的是为遗留代码创建一个自定义异常,并将遗留代码抛出的异常放入其内部异常中。然后你可以在主应用中忽略自定义异常,但在单元测试中仍然会抛出它们 例如: try { //rubbish legacy code which will throw all kinds of exceptions } catch(Exce
如何断言在单元测试中调用了异常。如果代码之外没有人会看到它,为什么要在意呢?我不会对这种不向调用方公开的功能进行单元测试。我要做的是为遗留代码创建一个自定义异常,并将遗留代码抛出的异常放入其内部异常中。然后你可以在主应用中忽略自定义异常,但在单元测试中仍然会抛出它们 例如:
try
{
//rubbish legacy code which will throw all kinds of exceptions
}
catch(Exception ex)
{
throw new CustomException(message: "something bad happened", innerException: ex);
}
然后通常可以执行以下操作:
try
{
MethodWhichCallsRubbishLegacyStuffAndWillProbablyThrowException();
}
catch (CustomException c)
{
//do nothing or better yet - logging!
}
catch (Exception ex)
{
//handle potential exceptions caused elsewhere
}
现在,在单元测试中,您可以针对CustomException或抛出的特定InnerException进行断言。根据您在问题中的评论:
如果我的一条消息由于遗留应用程序接口而失败,我将向一线支持发送一封电子邮件,该接口可能引发我正在处理的许多不同异常。如果我的测试能够断言抛出并处理了异常,那就太好了 最干净的处理方法是确保处理异常并将其作为电子邮件传递的代码作为构造函数上的接口接收emailer 然后,您可以模拟电子邮件处理程序,将其传递给您的测试代码,并断言它被赋予了正确的异常类型 大概是这样的:
public interface IExceptionEmailer {
void HandleGenericException( Exception e );
void HandleYourExceptionTypeA ( ExceptionTypeA e );
// ... continue with your specific exceptions
}
public class YourClassThatCatchesExceptions( ){
private IExceptionEmailer emailer;
public void TheMethodThatCatches ( ) {
try {
// actions
} catch ( ExceptionTypeA e ) {
this.emailer.HandleYourExceptionTypeA( e );
} catch ( Exception e ) {
this.emailer.HandleGenericException( e );
}
}
public YourClassThatCatchesExceptions( IExceptionEmailer emailer ) {
this.emailer = emailer;
}
}
然后您的测试类假设Moq和Xunit为:
public class GivenAnExceptionEmailer ( ) {
[Fact]
public void WhenYourSpecificActionHappens ( ) {
var emailer = new Mock<IExceptionEmailer>();
// ARRANGE the rest of your system here
var target = new YourClassThatCatchesExceptions( emailer.Object );
// do whatever ACTions needed here to make it throw
target.Whatever( );
// then ASSERT that the emailer was given correct type
// this will fail if the exception wasn't thrown or wasn't
// properly caught and handled.
emailer.Verify ( e =>
e.HandleYourExceptionTypeA ( It.IsAny<ExceptionTypeA>( )),
Times.Once( )
);
}
}
我还没有测试过,所以你可能会发现语法问题,但是,这会隔离你的系统,这样你就可以验证你在类中期望的捕捉异常的准确行为,你的管理员会感谢你没有用一堆测试电子邮件发垃圾邮件 我做过类似的事情,不确定这是否是好的做法 第一:
[TestMethod]
public void MethodName_TestErrorMessage_When_SomeException()
{
// Arrange
const string ExpectedMessgae= "Error in Application ";
this.MockedInterface.Setup(x=>x.MethodCall()).Throws<SomeException>();
// Act
var result=this.Controller.Action() as JsonResult;
// Assert
Assert.AreEqual(ExpectedMessage, result.Data.ToString());
}
这只是一个示例,但通常情况下,如果您没有重新引发异常,并且它已在代码中处理,那么我们可以验证消息是否正确。但这也意味着至少您没有丢失代码中的堆栈跟踪并返回它。如果有人帮我改进,我将不胜感激。
另一种方法是ExcpectedException属性,不应为此处理异常 抛出异常的是什么?如果你正在吞咽它,并且你无法测试抛出它的任何东西是否已经抛出它,你基本上是说你不希望有任何它抛出的记录……如果我的一条消息由于遗留应用程序接口而失败,我将向一线支持发送一封电子邮件,该接口可能抛出许多我正在处理的不同异常。如果我的测试能够断言抛出并处理了异常,那就太好了。您可以更改catch块中的状态,并在单元测试中断言该状态。否则,如果您通过mock using exception抛出异常,那么就足以验证是否调用了预期的方法。您可以提供任何代码吗?为什么不将其作为注释发布?我使用单元测试帮助团队中的其他开发人员理解生产代码。一个明确的测试详细说明了正在处理的异常,这将教育他们为什么要处理这个异常我使用单元测试来帮助团队中的其他开发人员真正理解生产代码??您可以通过代码中的注释来执行此解释。使用单元测试“测试您的软件”。@hatchet,因为这回答了一个问题:不要对该功能进行单元测试。