Chcel by som napísať test jednotky, ktorý overí, či moja metóda neprijíma neplatné argumenty. Platnosť argumentov sa kontroluje pomocou kódu zmluvy Contract.Requires
hovor. Prečo by som chcel testovať zmluvy? Považujem svoje testy za druh špecifikácie metódy (čo je vlastne myšlienka prevzatá z TDD), takže testovaním, či metóda pre niektoré argumenty zlyháva, určujem, že tieto argumenty by sa nemali používať.
Problém je v tom, že odkedy som začal používať zmluvy na kód, nemôžem testovať kontrakty na metódy, pretože nemám prístup k výnimke, ktorá je vyvolaná Contract.Requires
. Dokážem chytiť generické Exception
ale to jednoducho nie je pekné ... Existuje odporúčaný / podporovaný spôsob, ako otestovať sadu kontraktov pomocou Code Contracts?
Zdá sa mi, že zmluvy Code Code skutočne nepodporujú testovanie jednotiek ...
EDIT: Môj príklad z testu (som nútený zachytiť všeobecnú výnimku)
[ExpectedException(typeof(Exception), AllowDerivedTypes = true)]
public void Compute_Throws_ForNullArgument()
{
new ComputingService().Compute(null);
}
odpovede:
3 pre odpoveď č. 1Môžete hák do Contract.ContractFailed
event.
Toto sa zvýši pred vyvolaním výnimky. Môžete to kombinovať s chytaním Exception
byť si celkom istý, že to predstavuje zlyhanie zmluvy
public void VerifyContract(Action action) {
bool failed = false;
bool thrown = false;
EventHandler e = (sender, e) => { failed = true; }
Contract.ContractFailed += e;
try {
action();
} catch (Execption) {
Assert.True(failed);
thrown = true;
} finally {
Contract.ContractFailed -= e;
}
Assert.True(thrown);
}
2 pre odpoveď č. 2
Nemôžete výslovne chytiť správny typ výnimky, ale mohli by ste chytiť Exception
a potom skontrolujte, či je to a ContractException
pomocou reflexie (v opačnom prípade rethrow).
To by bolo škaredé všade, ale stačí to urobiť raz:
public static void AssertContractFailure(Action action)
{
try
{
action();
Assert.Fail("Expected contract violation");
}
catch (Exception e)
{
if (...) // I can"t remember offhand what you"d need to check
{
throw;
}
}
}
potom:
AssertContractFailure(() => SomeContractViolation(...));
Momentálne, ak to máte v triede pomocníkov, musíte hovor kvalifikovať všade, ale od C # 6 dúfam, že ho budete môcť ľahko importovať :)
0 pre odpoveď č. 3
Ak si dobre pamätám, zmluvy vyvolávajú výnimky, ak Requires
konštrukcia zlyhá, a ak Return
konštrukt zlyhá. Preto určite na účely testovania jednotiek musíte jednoducho chytiť tieto výnimky a budete vedieť, či bola zmluva porušená alebo nie.