当前位置:  开发笔记 > 编程语言 > 正文

单元测试无效方法?

如何解决《单元测试无效方法?》经验,为你挑选了6个好方法。

对不返回任何内容的方法进行单元测试的最佳方法是什么?特别是在c#中.

我真正想要测试的是一个获取日志文件并解析特定字符串的方法.然后将字符串插入数据库.没有什么比以前没有做过但对TDD非常新的我想知道是否有可能测试这个或者它是否真的没有经过测试.



1> Gishu..:

如果方法没有返回任何内容,则它是以下之一

命令式 - 你要么要求对象对自己做一些事情......例如改变状态(不要期待任何确认......它假定它会被完成)

信息 - 只是分别通知某人发生了事情(没有期待行动或回应).

命令式方法 - 您可以验证任务是否实际执行.验证是否实际发生了状态更改.例如

void DeductFromBalance( dAmount ) 

可以通过验证此消息的余额是否确实小于dAmount的初始值来进行测试

信息方法 - 作为对象的公共接口的成员很少见...因此通常不进行单元测试.但是,如果必须,您可以验证是否要对通知进行处理.例如

void OnAccountDebit( dAmount )  // emails account holder with info

可以通过验证是否正在发送电子邮件来进行测试

发布有关您的实际方法的更多详细信息,人们将能够更好地回答.
更新:您的方法正在做两件事.我实际上将它分成两种方法,现在可以独立测试.

string[] ExamineLogFileForX( string sFileName );
void InsertStringsIntoDatabase( string[] );

通过为第一个方法提供一个虚拟文件和预期的字符串,可以很容易地验证String [].第二个有点棘手..你可以使用Mock(google或在模拟框架上搜索stackoverflow)来模仿数据库或点击实际数据库并验证字符串是否插入到正确的位置.检查这个帖子是否有一些好书...如果你处于紧张状态,我会推荐语用单元测试.
在代码中它将被用作

InsertStringsIntoDatabase( ExamineLogFileForX( "c:\OMG.log" ) );



2> Jon Skeet..:

测试它的副作用.这包括:

它会抛出任何异常吗?(如果它应该,检查它是否.如果它不应该,尝试一些极端情况,如果你不小心可能 - 空参数是最明显的事情.)

它与参数配合得很好吗?(如果它们是可变的,它会在不应该变异的情况下变异,反之亦然吗?)

它对您调用它的对象/类型的状态是否有正确的影响?

当然,你可以测试多少是有限的.例如,您通常无法测试每个可能的输入.实用性测试 - 足以让您确信您的代码设计得恰当并且正确实现,并且足以充当调用者可能期望的补充文档.



3> David Schmit..:

一如既往:测试该方法应该做什么!

它应该在某个地方改变全球状态(uuh,代码味道!)吗?

它应该调用接口吗?

使用错误的参数调用时是否会抛出异常?

使用正确的参数调用时是否应该抛出异常?

应该是 ...?



4> Suamere..:

Void返回类型/子例程是旧闻.我没有等制成的返回类型为void(除非我是极端懒惰)8年(从这个答案的时间,所以只是有点被问这个问题之前).

而不是像这样的方法:

public void SendEmailToCustomer()

创建一个遵循Microsoft的int.TryParse()范例的方法:

public bool TrySendEmailToCustomer()

也许没有任何信息需要您的方法返回以便长期使用,但在执行其工作后返回方法的状态对调用者来说是一个巨大的用途.

此外,布尔不是唯一的州类型.以前制作的子程序有多次实际上可以返回三种或更多种不同的状态(Good,Normal,Bad等).在那些情况下,你只是使用

public StateEnum TrySendEmailToCustomer()

然而,尽管Try-Paradigm在某种程度上回答了关于如何测试void返回的问题,但还有其他考虑因素.例如,在/一个"TDD"周期之后,你会"重构",并注意你正在做的两件事情与你的方法......从而打破了"单一职责原则." 所以应该先照顾好.其次,你可能已经认识到依赖...你正在触及"持久"数据.

如果您正在使用相关方法中的数据访问内容,则需要重构为n层或n层架构.但是我们可以假设当你说"然后将字符串插入数据库"时,你实际上意味着你正在调用业务逻辑层或其他东西.呀,我们会假设的.

实例化对象后,您现在了解对象具有依赖关系.这是当您需要决定是否要对对象或方法执行依赖注入时.这意味着您的构造函数或有问题的方法需要一个新的参数:

public  (IBusinessDataEtc otherLayerOrTierObject, string[] stuffToInsert)

现在,你可以接受你的业务/数据层对象的接口,你可以在单元测试嘲笑它,并没有相关性或害怕"意外"集成测试.

因此,在您的实时代码中,您传入一个REAL IBusinessDataEtc对象.但是在单元测试中,您传入一个MOCK IBusinessDataEtc对象.在该Mock中,您可以包含非接口属性,int XMethodWasCalledCount或者在调用接口方法时更新其状态的内容.

因此,您的单元测试将通过您的方法-In-Question,执行他们拥有的任何逻辑,并在您的IBusinessDataEtc对象中调用一个或两个或一组选定的方法.当您在单元测试结束时执行断言时,您现在需要测试几件事.

    现在是Try-Paradigm方法的"子程序"的状态.

    你的Mock IBusinessDataEtc对象的状态.

有关构建级别的依赖注入思想的更多信息......因为它们与单元测试有关...请查看构思器设计模式.它为您拥有的每个当前接口/类增加了一个接口和类,但它们非常小,并且为更好的单元测试提供了巨大的功能增加.



5> 小智..:

尝试这个:

[TestMethod]
public void TestSomething()
{
    try
    {
        YourMethodCall();
        Assert.IsTrue(true);
    }
    catch {
        Assert.IsTrue(false);
    }
}


[`ExpectedAttribute`](https://msdn.microsoft.com/zh-cn/library/microsoft.visualstudio.testtools.unittesting.expectedexceptionattribute.aspx)旨在使此测试更加清晰。

6> Keith Nichol..:

它会对一个对象产生一些影响....查询效果的结果.如果它没有明显效果,那就不值得单元测试了!

推荐阅读
贴进你的心聆听你的世界
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有