Da Sie Linq to Sql verwenden, finden Sie hier ein Beispiel zum Testen des von Ihnen erwähnten Szenarios mit NUnit und Moq. Ich kenne die genauen Details Ihres DataContext nicht und weiß nicht, was Sie darin zur Verfügung haben. Bearbeiten Sie für Ihre Bedürfnisse.
Sie müssen den DataContext mit einer benutzerdefinierten Klasse umschließen. Sie können den DataContext nicht mit Moq verspotten. Sie können SqlException auch nicht verspotten, da es versiegelt ist. Sie müssen es mit Ihrer eigenen Ausnahmeklasse umschließen. Es ist nicht allzu schwierig, diese beiden Dinge zu erreichen.
Beginnen wir mit der Erstellung unseres Tests:
[Test]
public void FindBy_When_something_goes_wrong_Should_handle_the_CustomSqlException()
{
var mockDataContextWrapper = new Mock<IDataContextWrapper>();
mockDataContextWrapper.Setup(x => x.Table<User>()).Throws<CustomSqlException>();
IUserResository userRespoistory = new UserRepository(mockDataContextWrapper.Object);
// Now, because we have mocked everything and we are using dependency injection.
// When FindBy is called, instead of getting a user, we will get a CustomSqlException
// Now, inside of FindBy, wrap the call to the DataContextWrapper inside a try catch
// and handle the exception, then test that you handled it, like mocking a logger, then passing it into the repository and verifying that logMessage was called
User user = userRepository.FindBy(1);
}
Lassen Sie uns den Test implementieren. Lassen Sie uns zuerst unsere Linq-to-Sql-Aufrufe mit dem Repository-Muster umbrechen:
public interface IUserRepository
{
User FindBy(int id);
}
public class UserRepository : IUserRepository
{
public IDataContextWrapper DataContextWrapper { get; protected set; }
public UserRepository(IDataContextWrapper dataContextWrapper)
{
DataContextWrapper = dataContextWrapper;
}
public User FindBy(int id)
{
return DataContextWrapper.Table<User>().SingleOrDefault(u => u.UserID == id);
}
}
Als nächstes erstellen Sie den IDataContextWrapper so, dass Sie diesen Blog-Beitrag zu diesem Thema anzeigen können , meiner unterscheidet sich ein wenig:
public interface IDataContextWrapper : IDisposable
{
Table<T> Table<T>() where T : class;
}
Erstellen Sie als Nächstes die CustomSqlException-Klasse:
public class CustomSqlException : Exception
{
public CustomSqlException()
{
}
public CustomSqlException(string message, SqlException innerException) : base(message, innerException)
{
}
}
Hier ist eine Beispielimplementierung des IDataContextWrapper:
public class DataContextWrapper<T> : IDataContextWrapper where T : DataContext, new()
{
private readonly T _db;
public DataContextWrapper()
{
var t = typeof(T);
_db = (T)Activator.CreateInstance(t);
}
public DataContextWrapper(string connectionString)
{
var t = typeof(T);
_db = (T)Activator.CreateInstance(t, connectionString);
}
public Table<TableName> Table<TableName>() where TableName : class
{
try
{
return (Table<TableName>) _db.GetTable(typeof (TableName));
}
catch (SqlException exception)
{
// Wrap the SqlException with our custom one
throw new CustomSqlException("Ooops...", exception);
}
}
// IDispoable Members
}