我是新來的單元測試和TDD和一般嘲笑,但我理解的一般想法。我的問題是如何嘲笑一個類,以便我可以調用實例化的方法,而不會在單元測試和實現類中出現重複的代碼?鑑於以下幾點:與微軟鼴鼠嘲笑一個簡單的課
//Simple Interface
public interface IProduct {
double price { get; set; }
double tax { get; set; }
double calculateCost();
}
//Simple Implementation of IProduct
public class SimpleProduct : IProduct {
private double _price;
private double _tax;
public double price {
get { return _price; }
set { _price = value; }
}
public double tax {
get { return _tax; }
set { _tax = value; }
}
public double calculateCost() {
return _price + (_price * _tax);
}
}
//Complex implementation of IProduct
public class MarylandProduct : IProduct {
private double _price;
private double _tax;
public double price {
get { return _price; }
set { _price = value; }
}
public double tax {
get { return _tax; }
set { _tax = value; }
}
public double calculateCost() {
if (_price <= 100) return _price + (_price * _tax);
else {
double returnValue = 100 + (100 * _tax); //use tax rate for first 100
returnValue += (_price - 100) + ((_price - 100) * 0.05); //use a flat rate of 0.05 for everything over 100
return returnValue;
}
}
}
我已經開始寫具有以下單元測試:
[TestMethod]
[HostType("Moles")]
public void molesCalculateCostforMarylandProduct() {
//Assign
MMarylandProduct marylandProduct = new MMarylandProduct();
marylandProduct.priceGet =() => 1000;
marylandProduct.taxGet =() => 0.07;
const double EXPECTED = 1052;
//Act
double actual = marylandProduct.Instance.calculateCost();
//Assert
Assert.AreEqual(EXPECTED, actual);
}
我希望能夠調用計算成本法無論是MarylandProduct
或在SimpleProduct
我單元測試。通常情況下,從數據庫中獲取價格和稅收,但是我已經做到這一點,以便將這些值存根以避免與數據庫或服務或任何其他提供這些值的任何耦合。最重要的是我想編寫一個單元測試,它將測試calculateCost()
的功能,而不必在單元測試中存儲該方法,因爲我知道在兩年內MarylandProduct
中的邏輯將改變。
因此,例如,一旦我有這個測試運行,我應該能夠進入並更改MarylandProduct.calculateCost()
的代碼,以增加一個「奢侈稅」,即將750添加到50以上的任何價格。如果我這樣做,我知道我的單元測試將失敗,因爲預期值爲1052,現在MarylandProduct
返回的結果不是預期的結果。
我只是想以這種錯誤的方式?我錯過了TDD的精神嗎? 感謝您的幫助。
編輯:(在其他嘲諷框架補充說,我都試過)
[TestMethod]
public void rhinoMockCalculateCostForMarylandProduct() {
//assign
IProduct marylandProduct = MockRepository.GenerateMock<IProduct>();
marylandProduct.Stub(price => price.price).Return(1000);
marylandProduct.Stub(tax => tax.tax).Return(0.07);
const double EXPECTED = 1052;
//act
double actual = marylandProduct.calculateCost();
//assert
Assert.AreEqual(EXPECTED, actual);
}
[TestMethod]
public void moqCalculateCostForMarylandProduct() {
//assign
var marylandProduct = new Mock<IProduct>();
marylandProduct.Setup(price => price.price).Returns(1000);
marylandProduct.Setup(tax => tax.tax).Returns(0.07);
const double EXPECTED = 1052;
//act
double actual = ((MarylandProduct)marylandProduct.Object).calculateCost();
//assert
Assert.AreEqual(EXPECTED, actual);
}
我想避免將重複的代碼在單元測試,並在類的實現,因爲如果在類變化的代碼那麼單元測試仍然會通過,因爲它沒有被改變。我知道在單元測試中可以做出這樣的改變,但是如果你有單元測試的TON,可以接受這種設計嗎?在你的單元測試和實現中有重複的代碼?
如果被測改變方法的行爲,因此必須測試。如果計算成本的輸出發生變化,那麼很自然地認爲你的斷言會失敗,因爲它不再準確,所以你將不得不更新你的測試。你不可能有你的蛋糕,也可以吃它 –
我沒有看到任何理由不使用正常的殘骸或嘲笑,而不是使用鼴鼠? –
@ jflood.net是的,但是我想避免重複代碼(單元測試中的1和實現中的1),只是因爲我在BO中更新它,所以單元測試仍然會通過,因爲代碼在單元測試中沒有改變,它仍然會通過。這是我想要避免的。 – szeliga