TDD原则:
很公平,这看起来非常简单。但是,在下面的例子中,这个原则导致重新测试同样的事情。这导致了top 5 TDD mistakes article.中列出的第二和第三大错误,其中包括太多的错误设置"并且"太多的断言"。
示例:
MyClass = function ()
{
var self = this;
self.Tasks = [];
self.IsExpanded = false;
var _IsLoaded = false;
//Private
function _LoadTasks()
{
//api call to load task
_SortTasks();
};
//Private
function _SortTasks(tasks)
{
//Sort self.Tasks array
};
//Public
self.Method3 = function ()
{
//Do stuff
if (HasDoneSomething)
{
_SortTasks();
}
};
//Public
self.Method2 = function (param)
{
//Do stuff
_SortTasks();
}
//Public
self.Method1 = function ()
{
if (self.IsExpanded)
_Collapse();
else
_Expand();
};
//Private
function _Expand()
{
if (!_IsLoaded)
{
_LoadTasks();
}
self.IsExpanded = true;
};
//Private
function _Collapse()
{
self.IsExpanded = false;
};
}
在上面的示例中,三种公共方法可能会影响任务的顺序。这导致在多次测试中重复排序的排序顺序。
test("Some test 2", 2, function ()
{
//Setup
var myClass = Builder.Build();
//Action
myClass.Method2(SomeParam);
//Assertion
ok( jobWasDoneProperly, "Task should now be started");
ok( resuledSortIsGood, "Task started was moved after already started tasks and before unstarted ones");
});
test("Some test 3", 3, function ()
{
//Setup
var myClass = Builder.Build();
//Action
myClass.Method3();
//Assertion
ok( taskLoadedCorrectly, "Tasks are loaded");
ok( taskAreExpanded, "Tasks are expanded");
ok( resuledSortIsGood, "Task started was moved after already started tasks and before unstarted ones");
});
对排序进行断言需要一些设置来验证结果排序。因此导致错误,如前所述必须进行大量设置。
问题可以通过测试"私人"轻松解决。方法" SortTasks"。这样,我只能断言" SortTask"用间谍调用,而不是实际测试"方法1","方法2"和方法3"。这并没有减少断言次数,但由于需要的验证较少,因此确实减少了设置的长度。但是,这表明代码中有异味,因为它会违反TDD原则。
在c#中,单向将创建一个新的类名" TaskList"继承List。实现一个公共排序方法。然后使用这个类来保存"任务"在" MyClass"而不是数组。通过这种方式,我们不会违反规则并且不会测试私人方法"一切都会很好。但是我在javascript中,我的数组实际上是一个Knockout obserbaleArrays,我简单地检查过是否有可能在javascript中继承一个数组。这似乎有可能,但我没有兴趣去那里,因为它似乎没有内置,太复杂。我不想保持这样的事情。
在尊重“不要测试私人方法”的情况下,在这个问题上测试排序的正确方法是什么?规则?
答案 0 :(得分:-1)
首先在TDD中,测试数量与您的代码量相比还不够。 对于这段代码,您可能会获得200多行测试。
你说的正确,在C#中你会从列表中继承,而你可能会通过构造函数注入它。你可以轻松地与间谍一起做。
你应该测试整个SUT的结果,所以如果你的sut正在做某事,并且为了实现它而对它进行排序,你就不应该测试排序 - 或者通过间谍来看看会发生什么。
您也可以轻松实现“私人”功能
MyClass = function(){
_function privateFunc(){}
}
现在你无法从外面访问它
此外,如果您是JS新手,我建议您尝试使用jasmine进行测试,这对C#开发人员非常有用