2012-08-08 36 views
1

因为我没有得到我的头单元测试。放弃我的思维单元测试

我有一个服务

public interface IMyService 
{ 
    public List<Person> GetRandomPeople(); 
} 

然后在我的MVC项目我有这个服务的实现

​​3210

然后在我的控制器

public HomeController : Controller 
{ 
    IMyService _myService; 
    public HomeController(IMyService myService) 
    { 
     _myService = myService 
    } 
} 

然后在行动方法我会用

public ActionResult CreateRandom() 
{ 
    List<Person> people = _myService.GetRandomPeople(); 
    return View(people) 
} 

注:人员回购在我的服务中,只是很快输入了这个,所以我有回购。

我的问题:我将如何测试我的服务实施在我的测试项目。我现在真的陷入了困境,我认为这是TDD未来的“光照”时刻。

在此先感谢。

+0

我不明白你的问题。 'MyService'是一个普通的类,所以就像那样测试它。 – 2012-08-08 12:21:33

+1

我不同意;我会考虑这个话题。这是开发新手单元测试,存储库模式和依赖注入的常见问题。请记住,这是[爱的夏天](http://blog.stackoverflow.com/2012/07/kicking-off-the-summer-of-love/)。 :) – TrueWill 2012-08-08 13:18:39

+0

请你能在这里发布你的MyService代码为什么你不能测试? – 2012-08-08 16:09:32

回答

2

将服务接口注入控制器的目的是让您单独测试控制器。为了测试这个,你传入一个模拟或伪造的IMyService。

根据您的服务如何实施,您可能需要测试您的服务集成测试。这些应该与你的单元测试分开(因为你不想连续运行它们)。

例如,假设IMyService是使用Entity Framework实现的。你需要实际运行LINQ to Entities来对数据库进行测试。你可以使用本地数据库,你可以用EF创建并快速填充数据库等。这些不是单元测试(它们使用I/O),但它们仍然很重要。

其他持久性框架可能允许您针对内存数据集进行测试。没关系;我仍然认为这是一个集成测试(你的代码+框架),并将它从单元测试中分离出来。

诀窍是保持业务逻辑不受服务实现的影响。尽可能限制纯数据访问代码。你想用单元测试来测试你的业务逻辑。

编辑:

为了解决这个问题的意见(“当你需要创建存根”):

创建存根,假货,测试双打,或嘲笑(有很多的术语)当你有一个你想要隔离测试的类(被测系统或SUT)并且该类已经注入了依赖关系。

这些依赖将会以某种方式抽象 - 接口,抽象类,类与虚拟方法,委托等

你的生产代码将传递(类袭击的数据库,例如具体实现)。您的测试代码将通过测试实现。您可以传递一个简单的存根实现(只需在您的测试项目中编写一个虚拟类来实现接口并为其成员返回固定值),或者您可以拥有一个更好的实现来检测调用的是什么以及调用什么参数被传递(一个模拟对象)。您可以手动编写所有这些内容。它变得乏味,许多测试人员使用模拟对象框架(也称为隔离框架)。有很多(对于任何给定的语言,通常有几个);我倾向于在.NET中使用NSubstituteMoq

学习编写测试需要时间。它帮助我阅读了关于这个主题的几本书。博客帖子可能无法提供足够的背景。 (关闭)question here有一些很好的建议。

简短的回答是,当您的测试需要时,您可以创建存根或嘲笑。

+0

P.S.我会返回IEnumerable 而不是List。列表是一个实现细节。 – TrueWill 2012-08-08 13:20:24

+0

使用EF,可以使用Mocking Context Generator来简化单元测试:http://blogofrab.blogspot.com/2010/08/maintenance-free-mocking-for-unit.html – 2012-08-08 21:46:40

+0

@JakubKaleta - 有趣的链接。我认为[对LINQ to Entities的限制](http://msdn.microsoft.com/zh-cn/library/bb738550)需要验证的集成测试。 – TrueWill 2012-08-08 23:45:10