单元测试在调用时抛出System.Security.SecurityException

时间:2015-04-21 16:55:10

标签: c# unit-testing exception smtpclient

我有一个类,它有一个方法可以将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";
}

1 个答案:

答案 0 :(得分:0)

您应该能够创建一个模拟客户端,您可以使用它来验证您希望在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正如您所期望的那样工作。所以你假装或嘲笑它,只是检查方法是否按照你的预期被调用。