2011-05-20 91 views
1

给出以下方法我可以测试什么和如何测试?单元测试帮助

public void DoSomething 
{ 
   Get Db record  
   Update Db the record 
   Log History in Db 
   Send an email notification 
} 
+2

你在这方面做得太多了。如果你坚持单一责任原则(S.O.L.I.的一部分)。D)那么你会发现测试更容易,因为你一次只测试一件事情。你也会发现你的代码也更容易维护。 – 2011-05-20 22:39:45

+0

如果你看看SOLID的其余部分,你还会发现一大堆其他的东西让单元测试变得更容易。 – 2011-05-20 22:40:32

回答

1

首先,我同意其他海报,这种方法做得太多。我个人认为它只做Db的东西,然后让我的应用程序层记录操作并发送电子邮件。这就是说,到单元测试这种方法,我会做以下(在C#):

首先,给该方法在这样的构造存在类:

public MyClass(
    IRepository repository, 
    ILoggingService loggingService, 
    INotificationClient notificationClient) 

...其中IRepository是一个接口是这样的:

interface IRepository 
{ 
    Db GetDbRecord(); 
    void UpdateDbRecord(Db record); 
} 

...的ILoggingService是这样的:

interface ILoggingService 
{ 
    void LogInformation(string information); 
} 

...和INotificationClient是这样的:

interface INotificationClient 
{ 
    void SendNotification(Db record); 
} 

在构造体,分配传入的参数给私人,只读字段MyClass

接下来,在DoSomething方法,从IRepository得到Db记录,更新和保存回IRepository。使用ILoggingService记录历史记录,然后在INotificationClient上拨打SendNotification()

最后,在您的单元测试中,使用模拟框架(如Moq)来模拟每个接口之一。通过嘲笑的对象成MyClass一个新的实例,调用DoSomething(),然后验证您的嘲笑IRepository被要求更新Db对象,你的嘲笑ILoggingService已要求登录的消息,你的嘲笑INotificationClient已要求SendNotification()。这就是说:

Db record = new Db(); 

var mockRepository = new Mock<IRepository>(); 
mockRepository.Setup(r => r.GetDbRecord()).Returns(record); 

var mockLoggingService = new Mock<ILoggingService>(); 

var mockNotificationClient = new Mock<INotificationClient>(); 

new MyClass(
    mockRepository.Object, 
    mockLoggingService.Object, 
    mockNotificationClient.Object).DoSomething(); 

// NUnit syntax: 
Assert.That(record["ExpectedUpdatedField"], Is.EqualTo("ExpectedUpdatedValue")); 

mockRepository.Verify(r => r.UpdateDbRecord(record), Times.Exactly(1)); 

mockLoggingService.Verify(ls => ls.LogInformation(It.IsAny<string>()), Times.Exactly(1)); 

mockNotificationClient.Verify(nc => nc.SendNotification(record), Time.Exactly(1)); 

运行的系统中,你将注入的MyClass'依赖正确的实现,然后你共享之间更连贯的对象的责任。

有点啰嗦,但这就是我该怎么做:)

0

对于单元测试 - 您没有“单元”方法。它做了太多事情。为每个作业提取方法并测试这些方法。

通常,单元测试不包括数据库更改等,因此您必须查看如何攻击该部分。它将取决于你使用的框架等。你可以模拟数据库方法并确认你正在调用它们。不要去看看数据是否添加到数据库等。这不是单元测试,你会开始意识到,你的测试变得片状,慢,不能并行等。

有集成测试/分贝测试数据部分并确保回滚您修改的任何数据。还要确保没有测试依赖于其他测试所做的更改。