【问题标题】:Unit test throws System.Security.SecurityException on call单元测试在调用时抛出 System.Security.SecurityException
【发布时间】:2015-06-28 23:45:45
【问题描述】:

我有一个类,它有一个向调用者返回 smtpclient 的方法。当从类本身调用时,它工作正常,但是当我从单元测试中调用它时,我得到了

Test Name:  SmtpTest
Test FullName:  WatchDogTests.UnitTest1.SmtpTest
Test Source:    REDACTED
Test Outcome:   Failed
Test Duration:  0:00:00.0778799

Result Message: 
Test method WatchDogTests.UnitTest1.SmtpTest threw exception: 
System.Security.SecurityException: Request for the permission of type 'System.Net.Mail.SmtpPermission, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.
Result StackTrace:  
at System.Security.CodeAccessSecurityEngine.Check(Object demand, StackCrawlMark& stackMark, Boolean isPermSet)
   at System.Security.CodeAccessPermission.Demand()
   at System.Net.Mail.SmtpClient.Initialize()
   at System.Net.Mail.SmtpClient..ctor(String host)
   at WatchDogV2.WatchDog.SetSmtp()
   at WatchDogTests.UnitTest1.SmtpTest()

函数长这样

SmtpClient foo()
{
    SmtpClient temp = new SmtpClient("mysmtphost.com");
    temp.Port = 25;
    temp.UseDefaultCredentials = True;
    return temp;
}

单元测试中的调用是这样的

void UnitTest1()
{
    WatchDog Watcher = new WatchDog();
    SmtpClient temp = Watcher.foo();
   //Assert some stuff
}

我觉得问题在于单元测试运行的信任级别低于实际类,但我还没有找到解决此问题的方法。

更新 1:关于如何使用 foo() 的更多上下文

void sendmsg(List<string> Message)
{
    SmtpClient client = foo():
    MailMessage msg = makemsg(Message);
    client.Send(msg);
}

SmtpClient foo()
{
    SmtpClient temp = new SmtpClient("mysmtphost.com");
    temp.Port = 25;
    temp.UseDefaultCredentials = True;
    return temp;
}

MailMessage makemsg(list<string> msg)
{
    MailMessage mail = new MailMessage();
    mail.to.add("recipient@host.com");
    mail.from = "sender@host.com";
    mail.body = msg; //In actuality a for loop that adds to the body
    mail.subject = "Watchdog report";
}

【问题讨论】:

  • 您可能不想在单元测试中实际连接到 smtp 客户端,对吗?你不想模拟一个 smtp 客户端吗?
  • 我想是的。我主要想检查函数中的连接是否正确设置。有没有办法将我的单元测试沙箱化,以便连接到模拟客户端?
  • 我们必须看看您的 Watcher 正在做什么,以便为您提供任何见解
  • 简而言之,一系列函数根据对sql server的一些调用生成一条消息。该消息被传递给创建 smtpclient 的函数,创建邮件消息,然后通过 smtpclient 发送邮件消息。
  • 贴出相关代码。你在使用像 Moq 这样的模拟框架吗?

标签: c# unit-testing exception smtpclient


【解决方案1】:

您应该能够创建一个模拟客户端,您可以使用它来验证您期望在 SmtpClient 上调用的方法实际上正在被调用。

这是使用 Moq 之类的模拟框架时的样子

var smtpMock = new Mock<SmtpClient>();
smtpMock.Setup(mock => mock.Send());

var watcher = new WatchDog();
watcher.Client = smtpMock.Object;

watcher.foo();

//verifies that the Send() method was called as expected
smptMock.Verify(mock => mock.Send(), Times.Once());

您想模拟SmtpClient 的原因是您只想测试您期望被调用的方法是否被调用。您可以假设SmtpClient 正在按照您的预期工作。因此,您可以伪造或模拟它,然后检查这些方法是否也按照您的预期被调用。

【讨论】:

    猜你喜欢
    • 2016-07-31
    • 1970-01-01
    • 1970-01-01
    • 2019-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-26
    • 2018-11-09
    相关资源
    最近更新 更多