2010-09-19 8 views
6

tengo el siguiente método:byte [] en LINQ to SQL y en una prueba de unidad que utiliza burlarse

User IDataContext.AuthenticateUser(string userName, string password) 
{ 
    byte[] hash = PasswordHasher.HashPassword(userName, password); 

    var query = 
     from e in mContext.GetTable<User>() 
     where e.Email == userName && e.Password == hash 
     select e; 

    return query.FirstOrDefault(); 
} 

Cuando mContext es una System.Data.Linq.DataContext todo funciona muy bien. Sin embargo, cuando mContext es un simulacro en memoria durante mi prueba de unión, la comparación entre e.Password y hash siempre devuelve false.

Si reescribo esta comparación como e.Password.SequenceEqual(hash), pasarán las pruebas de mi unidad, pero recibo una excepción cuando hablo con LinqToSql. (System.NotSupportedException:. El operador de consulta 'SequenceEqual' no es compatible)

¿Hay una manera que puedo escribir esta consulta que satisfaga mis pruebas unitarias con una maqueta en memoria, así como el componente de producción con LinqToSql?

Respuesta

3

Eso es interesante. No puedo pensar en una forma conveniente de interceptar a los iguales sin romper todo, pero: ¿son los nombres de usuario únicos? Puede solo incluir la condición de nombre de usuario en el LINQ, luego verificar el hash en C# normal. En términos de datos transferidos, hay poca diferencia entre pasarlo y recuperarlo, especialmente si lo optimizamos para el caso de éxito (en cuyo caso, este reduce los requisitos de IO).

Nota: devuelva el mismo resultado para "no encontrado" y "no coincide" si hace esto.

Dado que el byte [] ya no depende del tratamiento especial de LINQ-a-SQL, debería funcionar bien en su simulacro ahora.

var user = (by name).SingleOrDefault(); 
if(user==null) #fail 
bool hashMatch = /* compare array */ 
if (!hashMatch) #fail 
return user; 
+0

+1 - Al principio estaba haciendo lo mismo, pero luego me di cuenta de que podía reducir la solicitud de IO a * 1 * y simplemente comparar las contraseñas con LINQ normal. – TheCloudlessSky

0

Este no es un buen candidato para pruebas unitarias. ¿Qué valor se produce al probar la igualdad de SQL utilizando la igualdad de .Net?

En psuedocode, veo (en esencia) de tres llamadas de método:

HashPassword(); 
ConstructQuery(); 
FirstOrDefault(); 

Cada uno de estos tres llamados métodos pueden ser probados unidad. ¿Cuál es el punto de unidad probando el método original?