论坛首页 综合技术论坛

什么是“测试驱动开发”

浏览 71486 次
该帖已经被评为精华帖
作者 正文
   发表时间:2006-04-25  
实际上私有方法可能出现的情形有很多:
比如封装循环
比如一段有语义关系的顺序执行语句
比如封装对其他
比如按某种既定方式修改对象的状态
而且,很多情况下,私有方法根本不和依赖对象发生关系
0 请登录后投票
   发表时间:2006-04-25  
firebody 写道
charon 写道

看了这个代码。基本确认我们说的不是一个事情。
如果只是要验证comp2.logic3的传入参数,不必费那么大劲。因为EasyMock默认的就是equals方式的参数匹配。在外面构造好合适的result,result2不就行了。不理解为什么要自己构造IArgumentMatcher的实例(之前的不理解主要就在这里,不了解构造这个的必要性)
而要验证doSomeInternalLogic之类方法对状态的影响,这是间接方式。太琐碎了。而且不能应付大多数情况。

嗯,我也有这种感觉。
从测试代码来看,是比较evil的。
跟AssertEquals之类比起来确实没法比。

不过,不大理解的是,在私有方法改变状态的逻辑 上,除了改成protected和抽取出另外一个组件之外,似乎也就只有这么一个办法了。

我要验证doSomeInternalLogic的逻辑,就只能构造那两个ArgumentMatcher来进行验证。

还是不理解。你这里是通过验证comp2.logic3的输入参数来间接验证doSomeInternalLogic的,根本不需要构造ArgumentMatcher.
如果在某些场合下真的需要,那也只是需要合理实现被match对象的equals方法,而不是通过构造IArgumentMatcher的实例
0 请登录后投票
   发表时间:2006-04-25  
charon 写道
实际上私有方法可能出现的情形有很多:
比如封装循环
比如一段有语义关系的顺序执行语句
比如封装对其他
比如按某种既定方式修改对象的状态
而且,很多情况下,私有方法根本不和依赖对象发生关系

是啊,TDD怎么能够反映这种被私有化了的方法逻辑的设计意图呢?
这就是我提出我得那个doSOmeLogicInternal的根本意图啊,就是疑惑啊,TDD的测试代码里面如果没有反映这个被私有的逻辑的话,怎么能够完整的反映设计意图呢?
0 请登录后投票
   发表时间:2006-04-25  
charon 写道
firebody 写道
charon 写道

看了这个代码。基本确认我们说的不是一个事情。
如果只是要验证comp2.logic3的传入参数,不必费那么大劲。因为EasyMock默认的就是equals方式的参数匹配。在外面构造好合适的result,result2不就行了。不理解为什么要自己构造IArgumentMatcher的实例(之前的不理解主要就在这里,不了解构造这个的必要性)
而要验证doSomeInternalLogic之类方法对状态的影响,这是间接方式。太琐碎了。而且不能应付大多数情况。

嗯,我也有这种感觉。
从测试代码来看,是比较evil的。
跟AssertEquals之类比起来确实没法比。

不过,不大理解的是,在私有方法改变状态的逻辑 上,除了改成protected和抽取出另外一个组件之外,似乎也就只有这么一个办法了。

我要验证doSomeInternalLogic的逻辑,就只能构造那两个ArgumentMatcher来进行验证。

还是不理解。你这里是通过验证comp2.logic3的输入参数来间接验证doSomeInternalLogic的,根本不需要构造ArgumentMatcher.
如果在某些场合下真的需要,那也只是需要合理实现被match对象的equals方法,而不是通过构造ArgumentMatcher

我也不理解你的说法,你写写伪代码吧。
0 请登录后投票
   发表时间:2006-04-25  
所以我这里所有稍微有点意义的内务方法,都是protected。
而且,我的理解,这个不是TDD的需要,而是测试安全的需要。
至于TDD的推动开发,解决的不应当是个体方法的设计。这个层次的事情,很多方式都搞得定。TDD中广泛使用mock,使得大家能够在不预先实现想象中的对象就能搞定手头的事情,这是分治方法的一个非常好的表现。
0 请登录后投票
   发表时间:2006-04-25  
firebody 写道
我也不理解你的说法,你写写伪代码吧。


按照你附件里面的那个例子,我一般是这样做的:
public class MockTest extends TestCase {
    private static String TESTNAME1 = "aa";
    private static String TESTNAME2 = "b2";
    private static String TESTNAME2 = "fuck";

	A a;
	static Bean argB1;
	private void changeState(Bean b);{
		b.name = "changed";
	}
	public void logic(); {
		Bean b = new Bean(name:TESTNAME1);;
		Bean b2 = new Bean(name:TESTNAME2);;
		a.test(b,b2);;
		a.test(b,b2);;
		this.changeState(b);;
		
	}

	public void test(); {
		A aMock = createMock(A.class);;
		MockTest test = new MockTest();;
		test.a = aMock;
		
		aMock.test(new Bean(name:TESTNAME1);,new Bean(name:TESTNAME2););;
		aMock.test(new Bean(name:TESTNAME3);,new Bean(name:TESTNAME2););;
		replay(aMock);;

		test.logic();;
		verify(aMock);;
	}
}
0 请登录后投票
   发表时间:2006-04-25  
此时,要求Bean实现的equals方法中按照name判等
0 请登录后投票
   发表时间:2006-04-25  
charon 写道
此时,要求Bean实现的equals方法中按照name判等

你这个更不通用了,在简单的bean还行,因为equals就可以搞定。
万一我得bean的状态比较复杂呢? 还需要实现一个对应的equals方法?

而且,为了测试需要写一个符合测试规则的equals方法,感觉也不好吧。
0 请登录后投票
   发表时间:2006-04-25  
firebody 写道
charon 写道
此时,要求Bean实现的equals方法中按照name判等

你这个更不通用了,在简单的bean还行,因为equals就可以搞定。
万一我得bean的状态比较复杂呢? 还需要实现一个对应的equals方法?

而且,为了测试需要写一个符合测试规则的equals方法,感觉也不好吧。


那个bean是自己构造出来的,想要是什么状态就可以设置什么状态。
其实,那个equals不是一个符合测试规则的equals方法,而是一个一般的equals方法。而且,对象状态的判等,必须是可观测状态的判等,而且必须和equals的语义是一致的。这个和测试不测试没关系
在这个例子中,Bean实际上是不需要equals方法的,因为默认的够用了。
如果在构造状态比较多的bean对象的时候,适当注意那些引用对象的使用,默认的也够用了。
0 请登录后投票
   发表时间:2006-04-25  
charon 写道
firebody 写道
charon 写道
此时,要求Bean实现的equals方法中按照name判等

你这个更不通用了,在简单的bean还行,因为equals就可以搞定。
万一我得bean的状态比较复杂呢? 还需要实现一个对应的equals方法?

而且,为了测试需要写一个符合测试规则的equals方法,感觉也不好吧。


那个bean是自己构造出来的,想要是什么状态就是什么状态。
其实,那个equals不是一个符合测试规则的equals方法,而是一个一般的equals方法。
在这个例子中,Bean实际上是不需要equals方法的,因为默认的够用了。
如果在构造状态比较多的bean对象的时候,适当注意那些引用对象的使用,默认的也够用了。

呵呵,一般的equals我是不写的。除非有明确的需求。
0 请登录后投票
论坛首页 综合技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics