/ / Existuje nejaký spôsob, ako testovať zmluvy nastavené pomocou zmlúv s kódom? - c #, .net, výnimka, tdd, kódové zmluvy

Existuje nejaký spôsob, ako otestovať zmluvy zadané pomocou zmlúv s kódom? - c #, .net, výnimka, tdd, kódové zmluvy

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ď č. 1

Môžete hák do Contract.ContractFailed event.

http://msdn.microsoft.com/en-us/library/system.diagnostics.contracts.contract.contractfailed(v=vs.110).aspx

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.