对没有返回值的类进行单元测试? [英] Unit testing a class with no return value?

查看:795
本文介绍了对没有返回值的类进行单元测试?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在这个特定问题的教程中,我没有发现太多.

I didn't find much in tutorials on this specific question..

因此,我有一个名为"Job"的类,它具有公共ctor和单个公共Run()函数.该类中的所有内容都是私有的,并封装在该类中. (您可能还记得此此处仅测试的旧文章.中型课程的公开方法?,这对我的帮助很大)

So I have a class called 'Job' which has public ctors and a single public Run() function. Everything in the class is private and encapsulated in the class. (You may remember an older post here on this Testing only the public method on a mid sized class?, which replies helped me greatly)

此Run()方法可以完成很多工作-将excel文件作为输入,从中提取数据,向第三方数据供应商发送请求,获取结果并将其放入数据库中并记录开始/工作结束.

This Run() method does a bunch of things - takes an excel file as input, extracts data out of it, sends a request to a third party data vendor, takes the result and puts it in the database and logs the begining / end of the job.

此Job类在其run方法中使用3个单独的接口/类(IConnection将连接到第三方供应商并发送请求,IParser将解析结果,而IDataAccess会将结果保存到数据库中).因此,现在,Run()方法中唯一真正的逻辑就是提取excel输入并将其发送到其他类的链下.我创建了3个模拟类,并在Job类ctor上使用DI,一切都很好,很花哨……

This Job class uses 3 seperate interfaces / classes inside it's run method, (IConnection will connect to the third party vendor and send the request, IParser will parse the results, and IDataAccess will save the results to the database). So now, the only real logic inside my Run() method is extracting out the excel input and sending it down the chain of the other classes. I created 3 mock classes and use DI on the Job class ctor and everything is fine and dandy...

除了-我对如何测试Run()方法还有些迷惑-因为它是无效的,不会返回任何内容...

Except - I'm still a little lost on how the heck to test my Run() method - because it's void and doesn't return anything...

在这种情况下,我是否应该在Run()方法中添加一个返回值,该方法返回从Excel文件中提取了多少条记录?由于这是该函数现在唯一执行的逻辑..不会在真实代码中处理,而是在单元测试中...对我来说似乎有点难闻-但就我而言,我还是个新手真正的TDD值得关注...

In this case, should I add a return value to the Run() method that returns how many records were extracted from the Excel file? Since this is the only logic done in that function now.. this wouldn't be handled in real code, but would be in the unit tests... which seems a bit smelly to me - but i'm a newb as far as true TDD is concerned...

第二个问题-我是否应该创建一个名为IExcelExtractor的第四类,这对我有逻辑吗?还是这有点阶级爆炸?

Second question - should I created a fourth class called IExcelExtractor, which does that logic for me? Or is this a bit of class explosion??

即使我做了后者,如果Run()函数返回void并且它的所有工作都由实际上不执行任何操作的模拟对象执行,我将如何测试呢?我可以理解我的函数是否具有有意义的返回值...但是在这种情况下,我有点困惑.

Even if I did the latter, how would I test my Run() function if it returns void and all of its work is being carried out by mocked objects which really do nothing? I could understand if my function had a meaningful return value... but in this case I'm a but confused.

非常感谢您读完所有这些内容.

Thanks so much for reading through all this if you made it this far.

推荐答案

您所描述的通常被称为行为验证(与状态验证相对).它有其支持者和批评者,但是对于几种类别的课程来说,如果您要进行单元测试,它是镇上唯一的游戏.

What you're describing is often called behavior verification (as opposed to state verification). It's got its proponents and detractors, but for several categories of classes it's the only game in town if you want to unit test.

要对行为仅限于与协作者进行交互的类进行单元测试,通常需要传递模拟协作对象,这些对象的检测方式可以使您验证其方法是否已按预期方式被调用.

To unit test a class whose behavior is limited to interacting with collaborators, you typically pass mock collaborator objects that are instrumented in a way that allows you to verify their methods have been called in the way you expect.

如果要手动(在问题中提到的类)执行此操作(糟糕!),则可以创建一个实现IParserMockParser类,并添加记录是否以及如何调用其方法的属性.

If you were to do this by hand (yuck!) for the classes you mentioned in your question, you might create a MockParser class that implements IParser and adds properties that record if and how its methods were called.

最好使用模拟框架,该框架将动态创建模拟,指定模拟期望,并验证这些期望.

It's better to use mocking framework that will create the mocks on the fly, specify expections on them, and verify those expectations.

这些天我一直在使用 NMock2 ,测试看起来像这样:

I've been using NMock2 these days, and the tests look something like this:

// 'mockery' is the central framework object and Mock object factory
IParser mockParser   = mockery.NewMock<IParser>();

// Other dependencies omitted
Job     job          = new Job(mockParser);

// This just ensures this method is called so the return value doesn't matter
Expect.Once.On(mockParser).
    .Method("Parse").
    .WithAnyArguments().
    .Will(Return.Value(new object()));

job.Run();
mockery.VerifyAllExpectationsHaveBeenMet();

这篇关于对没有返回值的类进行单元测试?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆