c# - Contrato.Requiere tirar errores pex
c#-4.0 code-contracts (2)
Posible duplicado:
¿Cómo configura Pex para respetar los contratos de código?
Actualmente, cuando ejecuto una exploración pex, los contratos de código que creé en mis clases se tratan como errores en los resultados de exploración pex. Pensé que cuando ejecutaba la exploración pex utilizando contratos de código, las fallas del contrato deberían tratarse como el comportamiento esperado. Aquí está el código que causa las excepciones.
Método de prueba:
[PexMethod]
public void TestEquality(Guid userId, string username, string password, string securityQuestion, string securityAnswer)
{
UserSecurity user = UserTools.CreateUser(Guid.NewGuid(), username, password, securityQuestion, securityAnswer);
bool passwordResult = UserTools.VerifyInput(password, user.Password, user.PasswordSalt);
bool securityAnswerResult = UserTools.VerifyInput(securityAnswer, user.SecurityAnswer, user.SecurityAnswerSalt);
Assert.IsTrue(passwordResult, "Password did not correctly re-hash");
Assert.IsTrue(securityAnswerResult, "Security Answer did not correctly re-hash");
}
Llamada de método fallido:
public static UserSecurity CreateUser(Guid userId, string username, string password, string securityQuestion, string securityAnswer)
{
Contract.Requires(userId != Guid.Empty);
Contract.Requires(!string.IsNullOrWhiteSpace(username));
Contract.Requires(!string.IsNullOrWhiteSpace(password));
Contract.Requires(!string.IsNullOrWhiteSpace(securityQuestion));
Contract.Requires(!string.IsNullOrWhiteSpace(securityAnswer));
Contract.Ensures(Contract.Result<UserSecurity>() != null);
byte[] passwordSalt;
byte[] securityAnswerSalt;
return new UserSecurity
{
UserId = userId,
Username = username,
Password = SecurityUtilities.GenerateHash(password, out passwordSalt),
PasswordSalt = passwordSalt,
SecurityQuestion = securityQuestion,
SecurityAnswer = SecurityUtilities.GenerateHash(securityAnswer, out securityAnswerSalt),
SecurityAnswerSalt = securityAnswerSalt,
};
}
--- Descripción
failing test: ContractException, Precondition failed: !string.IsNullOrWhiteSpace(username)
Guid s0
= new Guid(default(int), (short)32, (short)32, default(byte), default(byte),
default(byte), default(byte), default(byte),
default(byte), default(byte), default(byte));
this.TestEquality(s0, (string)null, (string)null, (string)null, (string)null);
[TestMethod]
[PexGeneratedBy(typeof(HashTests))]
[PexRaisedContractException]
public void TestEqualityThrowsContractException173()
{
Guid s0
= new Guid(default(int), (short)32, (short)32, default(byte), default(byte),
default(byte), default(byte), default(byte),
default(byte), default(byte), default(byte));
this.TestEquality(s0, (string)null, (string)null, (string)null, (string)null);
}
Descubrí que si usa un reescritor de contrato estándar, desmarque la casilla de verificación en caso de fallo y deje que su código emita ArgumentNullException utilizando un argumento de Typed.
contract.Requires<ArgumentNullException>(i!=null);
cuando hagas esto, los métodos lanzarán argumentnullexceptions ... pex se comporta perfectamente bien con ellos.
En el momento de la compilación, usted todavía obtiene la verificación de contratos y la verificación estática como esperaría.
Parece que PexRaisedContractException no se comporta con su uso. Aunque no puedo decir que use ese atributo. Supongo que desde tu perspectiva mi camino es un trabajo alrededor;)
EDITAR: Pex debería generar esta prueba, pero la prueba debería lanzar el error y eso debería hacer que la prueba pase. el hecho de que esto no funcione me sugiere que el reescritor no está funcionando o que la excepción que se está lanzando no es el tipo de excepción que el atributo está buscando.
Según tengo entendido, según mi limitada experiencia con Pex, los métodos del Contract
definen las condiciones previas para alcanzar el método en el que se encuentran.
Contract.Requires(!string.IsNullOrWhiteSpace(username));
usted está diciendo que no debería haber forma de llegar a una declaración con un parámetro de nombre de usuario en blanco o en blanco. Pex está diciendo básicamente que estás equivocado. Esto es algo para lo que Pex es realmente bueno. Esto significa que tiene el potencial para una NullReferenceException
o que no está buscando un username
de username
vacío / espacio en blanco en alguna llamada a su método CreateUser
. Tu tarea, entonces, es encontrar dónde. Puede solucionar el problema manejando el username
de username
nulo / espacio en blanco en el método CreateUser
, luego deshaciéndose del Contract.Requires
requiere, o asegurándose de que todas las personas que llaman a CreateUser
pasan un nombre de usuario no nulo, no vacío. La mejor opción depende de su situación, creo, pero en casi todos los casos, manejaría el nombre de usuario nulo / espacio en blanco en el método CreateUser
. De esa manera, puede manejar el error con gracia en un lugar de su código.
Por supuesto, realmente debería ver qué interlocutor puede pasar nulos o espacios en blanco, ya que esto podría indicar un problema de validación de entrada del usuario, entre otros problemas potenciales.