首页 新闻 会员 周边

求救:单元测试疑惑

0
悬赏园豆:120 [已解决问题] 解决于 2012-11-08 17:21

最近MVC项目做单元测试,做的有点晕了。

网上看到这点:单元测试是最小的测试单元了,就是针对一个方法的

 

假设一个场景:类AB中有 A方法里调用了B方法,如下:

    public class AB
    {
        public bool A(bool isSuccess)
        {
            B();
            return isSuccess;
        }

        public void B()
        {
        }
    }

 

现在 要针对方法A 进行单元测试。

        [TestMethod()]
        public void ATest()
        {
            AB ab = new AB();
            bool result = ab.A(true);
            Assert.AreEqual(true, result);
        }

疑问:

1.A方法调用了B方法,如果B方法发生异常,导致A方法的单元测试没有通过,

  这种情况下单元测试失败了,是否能说明A方法有问题?(我觉的A方法本身没有问题,是B方法的问题)

 

2.如果发生上面的情况,单元测试,其实并没有测试出是B方法的问题,实际项目中,一个方法里跟N多对象和方法有关,这样的单元测试是不是没有什么意义,它找不出具体的问题出在哪里,要单元测试何用?

 

3. 想到 电灯和 开关的例子,要测试电灯是否是好的,首先要保证开关是好的,如果开关都不能保证好的,灯没亮,就不知道是灯的问题还是开关的问题。

同理,如果B方法不能保证能正常通过,那么说单元测试A方法将没有用,或者说A方法是不可测试的,可不可以这样说?

 

4.Mock对象就是模拟对象,模拟环境,我对这个Mock对象的理解是去模拟那些可能会导致失败的外部环境。如A方法,依赖B方法,Mock对象应该去模拟B方法,如果模拟不了,就是说A方法可测试性差,或者不能测试。 不知道能不能这样理解? (如果真是这样的话,那就是好多方法都无法单元测试了)

 

望各位园友 指点一下,在这谢谢啦!

问题补充:

问题:哪些对象需要 去Mock模拟?

答案:1.依赖的对象有风险(导致错误,导致失败);2.依赖的对象方法可能要操作数据库,将花大量的时间,这种代价比较大的。

如果符合这两条中的一条,就应该去 模拟。

 

对哪些地方要使用Mock等对象,不知道我的理解对不对?还有其它的 请补充

Qlin的主页 Qlin | 老鸟四级 | 园豆:2403
提问于:2012-11-07 14:44
< >
分享
最佳答案
0

其实你已经差不多找到问题的原因了.对这就是A方法可测试性差,它绝对依赖于B方法的具体实现.而不是它的抽象.

可测试性也是代码好坏的其中一个标准.很多不选择Web Form的原因也是它的可测试性差.当代码可测试性差时,你在单元测试里怎么搞也是没用的.

所以这时应该是重构,使其有更好的可测试性.

至于具体你上面的方法,不明白你为什么要在A里调用一个void的方法.所有也没有更好的重构建议.

收获园豆:40
zhangweiwen | 小虾三级 |园豆:904 | 2012-11-07 15:23

只是产生一个依赖关系,没有考虑到 void,能不能根据我的问题 一个个 具体说说

Qlin | 园豆:2403 (老鸟四级) | 2012-11-07 15:37

@Qlin: 

所有问题我的回答都一样,可测试性好的代码是不应该出现这些问题的.

单元测试就应该关注单个方法内的逻辑.

zhangweiwen | 园豆:904 (小虾三级) | 2012-11-07 15:43

@zhangweiwen: 

我不是写了我的理解不,那我认为的 结论 都是正确的?

Qlin | 园豆:2403 (老鸟四级) | 2012-11-07 15:47

@Qlin: 

你所有的问题和理解都是建立在一个"可测试性差"的前提上的,所以我觉得你的问题和理解都没有意义.

zhangweiwen | 园豆:904 (小虾三级) | 2012-11-07 15:51

@zhangweiwen: 

这里只是假设一个 外部影响的方法,真实 编程中,你可以看成是抽象,我想知道,我这样去理解单元测试是不是正确的。

Qlin | 园豆:2403 (老鸟四级) | 2012-11-07 15:56

@Qlin: 

如果是一个抽象的话,就可以使用桩对象来保证不会失败了,怎么会存在那些问题呢?

zhangweiwen | 园豆:904 (小虾三级) | 2012-11-07 16:17

@zhangweiwen: 

谢谢,看看 我的补充问题

Qlin | 园豆:2403 (老鸟四级) | 2012-11-07 16:22

@Qlin: 

你的理解对的,外部依赖都应该使用使用桩对象或者模拟对象来代替,因为我们要做的是单元测试,只关注单元(方法)本身.

zhangweiwen | 园豆:904 (小虾三级) | 2012-11-07 16:53
其他回答(4)
0

如果单元测试不能解决这样的问题,那么单元测试的实用性就很差了吧……

坐等大牛……

收获园豆:5
ms_water | 园豆:510 (小虾三级) | 2012-11-07 15:03

不晓得 我的问题 是不是 太幼稚了

支持(0) 反对(0) Qlin | 园豆:2403 (老鸟四级) | 2012-11-07 15:33

@Qlin: 不是幼稚……我理解的单元测试:测试单一功能,如果有其他因素影响这个方法,那就应该先把其他因素排除,怎么排除呢,我认为单元测试应该包含一段代码,类似测试前准备,以保证排除其他因素,所以单元测试代码总比代码多……

是不是这么理解呢?

支持(0) 反对(0) ms_water | 园豆:510 (小虾三级) | 2012-11-08 10:37
0
收获园豆:5
jason2013 | 园豆:1998 (小虾三级) | 2012-11-07 15:10

谢谢,看完,没有谈到 我的问题啊

支持(0) 反对(0) Qlin | 园豆:2403 (老鸟四级) | 2012-11-07 15:34
0

问题一:A方法还是有问题,因为作为一个测试只有通过了才算成功,不管什么原因造成失败都是失败。

问题二:单元测试是面向需求的,比如我的站点有个api,那么这个api的所有测试我会单独分出来,这里api里面调用了下面好多东西,每个不同的服务都有自己的一套测试,当然了在理想状态下就会去跑那些测试然后进一步缩小范围。不过书上的大牛的意见是从B=〉A每次都要从头跑一遍,如果有好的服务器当然快了,我的开发机还是算了,分开跑效果还是挺好的。另外也有人说他的方法写了十行,测试写了400行,写测试的时间还不如用来再次思考那个方法。

问题三:可以,所以测试有先后,就像依赖一样;

问题四:差不多,Mock确实给测试带来了很大的帮助,所以一个好的测试环境能事半功倍,比如Nbuilder也是个好帮手。是否可以测试是一个判断代码耦合性的好办法。

收获园豆:35
today4king | 园豆:3499 (老鸟四级) | 2012-11-07 15:35

问题一:如果是这样的话, 外部因素可能导致失败,A方法 不可测了,单元测试就没必要了?

问题二:你的意思是,要先测试 A方法依赖的B方法,如果B方法有依赖继续先测试里面依赖的方法,A方法最后测?

这样的话,工作量大了

问题三:有顺序? 我看好多测试方法无顺序,删掉也一样,还有救是好多方法都不会去测试,只是用抽象,用Mock去模拟。

问题四:Mock是可以去模拟环境,现在是 我不知道哪些东东需要去模拟,

比如我 认为的 可能导致失败的外部方法需要去模拟,如方法B 要模拟,不知道对不对?

支持(0) 反对(0) Qlin | 园豆:2403 (老鸟四级) | 2012-11-07 15:54

@Qlin: 

对待单元测试的时候我觉得最重要的不是看单元测试应该怎么做,而是单元测试是解决什么问题的。

比如我有个api,单元测试作为模拟宿主,在上线前跑一遍而已,这个时候的测试是没有mock的。

有时候我有比较复杂的业务处理的地方,那么我就需要把除业务逻辑外的代码给mock了,保证测试单元的独立和纯净。

我这人比较现实,能解决我问题的我才用,大牛说的话有时候是理论性质的,更多的是指导的意义,所以你说这个单元测试有没有意义或者是不是可以测试,就我的评判标准来说就是能不能解决我的问题。

支持(0) 反对(0) today4king | 园豆:3499 (老鸟四级) | 2012-11-08 12:06

@今昭: 

说的有理

支持(0) 反对(0) Qlin | 园豆:2403 (老鸟四级) | 2012-11-08 17:19
0

看过大侠的这本书 http://product.china-pub.com/14701 上面的问题你会豁然开朗

另外你举例的是两个public方法,一般的测试是针对public的测试,public方法之间互相调用应该改是设计有些问题

收获园豆:35
2012 | 园豆:21230 (高人七级) | 2012-11-08 12:48

谢谢,呵呵,还没看过这方面的书呢

支持(0) 反对(0) Qlin | 园豆:2403 (老鸟四级) | 2012-11-08 17:19
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册