Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Public class FileListRestore






{

public string LogicalName { get; set; }

public string Type { get; set; }

}

 

protected static string NameDb = " LessonProject";

 

protected static string TestDbName;

 

private void CopyDb(StandardKernel kernel, out FileInfo sandboxFile, out string connectionString)

{

var config = kernel.Get< IConfig> ();

var db = new DataContext(config.ConnectionStrings(" ConnectionString"));

 

TestDbName = string.Format(" {0}_{1}", NameDb, DateTime.Now.ToString(" yyyyMMdd_HHmmss"));

 

Console.WriteLine(" Create DB = " + TestDbName);

sandboxFile = new FileInfo(string.Format(" {0}\\{1}.bak", Sandbox, TestDbName));

var sandboxDir = new DirectoryInfo(Sandbox);

 

//backupFile

var textBackUp = string.Format(@" -- Backup the database

BACKUP DATABASE [{0}]

TO DISK = '{1}'

WITH COPY_ONLY",

NameDb, sandboxFile.FullName);

db.ExecuteCommand(textBackUp);

 

var restoreFileList = string.Format(" RESTORE FILELISTONLY FROM DISK = '{0}'", sandboxFile.FullName);

var fileListRestores = db.ExecuteQuery< FileListRestore> (restoreFileList).ToList();

var logicalDbName = fileListRestores.FirstOrDefault(p => p.Type == " D");

var logicalLogDbName = fileListRestores.FirstOrDefault(p => p.Type == " L");

 

var restoreDb = string.Format(" RESTORE DATABASE [{0}] FROM DISK = '{1}' WITH FILE = 1, MOVE N'{2}' TO N'{4}\\{0}.mdf', MOVE N'{3}' TO N'{4}\\{0}.ldf', NOUNLOAD, STATS = 10", TestDbName, sandboxFile.FullName, logicalDbName.LogicalName, logicalLogDbName.LogicalName, sandboxDir.FullName);

db.ExecuteCommand(restoreDb);

 

connectionString = config.ConnectionStrings(" ConnectionString").Replace(NameDb, TestDbName);

}

 

}

По порядку:

В строках

var config = kernel.Get< IConfig> ();

var db = new DataContext(config.ConnectionStrings(" ConnectionString"));

 

- получаем подключение к БД.

TestDbName = string.Format(" {0}_{1}", NameDb, DateTime.Now.ToString(" yyyyMMdd_HHmmss"));

Создаем наименование тестовой БД.

//backupFile

var textBackUp = string.Format(@" -- Backup the database

BACKUP DATABASE [{0}]

TO DISK = '{1}'

WITH COPY_ONLY",

NameDb, sandboxFile.FullName);

db.ExecuteCommand(textBackUp);

- выполняем бекап БД в папку Sandbox.

var restoreFileList = string.Format(" RESTORE FILELISTONLY FROM DISK = '{0}'", sandboxFile.FullName);

var fileListRestores = db.ExecuteQuery< FileListRestore> (restoreFileList).ToList();

var logicalDbName = fileListRestores.FirstOrDefault(p => p.Type == " D");

var logicalLogDbName = fileListRestores.FirstOrDefault(p => p.Type == " L");

- получаем логическое имя БД и файла логов, используя приведение к классу FIleListRestore.

var restoreDb = string.Format(" RESTORE DATABASE [{0}] FROM DISK = '{1}' WITH FILE = 1, MOVE N'{2}' TO N'{4}\\{0}.mdf', MOVE N'{3}' TO N'{4}\\{0}.ldf', NOUNLOAD, STATS = 10", TestDbName, sandboxFile.FullName, logicalDbName.LogicalName, logicalLogDbName.LogicalName, sandboxDir.FullName);

db.ExecuteCommand(restoreDb);

 

- восстанавливаем БД под другим именем (TestDbName)

connectionString = config.ConnectionStrings(" ConnectionString").Replace(NameDb, TestDbName);

- меняем connectionString.

И теперь можем спокойно проинициализировать IRepository к SqlRepository:

protected override void InitRepository(StandardKernel kernel)

{

FileInfo sandboxFile;

string connectionString;

CopyDb(kernel, out sandboxFile, out connectionString);

kernel.Bind< webTemplateDbDataContext> ().ToMethod(c => new webTemplateDbDataContext(connectionString));

kernel.Bind< IRepository> ().To< SqlRepository> ().InTransientScope();

sandboxFile.Delete();

}

Итак, у нас есть sandboxFile – это файл бекапа, и connectionString – это новая строка подключения (к дубликату БД). Мы копируем БД, связываем именно с SqlRepository, но базу подсовываем не основную. И с ней можно делать всё что угодно. Файл бекапа базы в конце удаляем.

И дописываем уже удаление тестовой БД, после прогона всех тестов:

private void RemoveDb()

{

var config = DependencyResolver.Current.GetService< IConfig> ();

 

var db = new DataContext(config.ConnectionStrings(" ConnectionString"));

 

var textCloseConnectionTestDb = string.Format(@" ALTER DATABASE [{0}] SET SINGLE_USER WITH ROLLBACK IMMEDIATE", TestDbName);

db.ExecuteCommand(textCloseConnectionTestDb);

 

var textDropTestDb = string.Format(@" DROP DATABASE [{0}]", TestDbName);

db.ExecuteCommand(textDropTestDb);

}

Используя TestDbName, закрываем подключение (а то оно активное), и удаляем базу данных.

Не забываем сделать копию Web.config:

xcopy $(SolutionDir)LessonProject\Web.config $(ProjectDir)Sandbox\ /y

Но кстати, иногда БД нет необходимости удалять. Например, мы хотим заполнить базу кучей данных автоматически, чтобы проверить поиск или пейджинг. Это мы рассмотрим ниже. А сейчас тест – реальное создание в БД записи:

[TestFixture]

public class DefaultUserControllerTest

{

[Test]

public void CreateUser_CreateNormalUser_CountPlusOne()

{

var repository = DependencyResolver.Current.GetService< IRepository> ();

 

var controller = DependencyResolver.Current.GetService< LessonProject.Areas.Default.Controllers.UserController> ();

 

var countBefore = repository.Users.Count();

var httpContext = new MockHttpContext().Object;

 

var route = new RouteData();

 

route.Values.Add(" controller", " User");

route.Values.Add(" action", " Register");

route.Values.Add(" area", " Default");

 

ControllerContext context = new ControllerContext(new RequestContext(httpContext, route), controller);

controller.ControllerContext = context;

 

controller.Session.Add(CaptchaImage.CaptchaValueKey, " 1111");

 

var registerUserView = new UserView()

{

ID = 0,

Email = " rollinx@gmail.com",

Password = " 123456",

ConfirmPassword = " 123456",

Captcha = " 1111",

BirthdateDay = 13,

BirthdateMonth = 9,

BirthdateYear = 1970

};

 

Validator.ValidateObject< UserView> (registerUserView);

controller.Register(registerUserView);

 

var countAfter = repository.Users.Count();

Assert.AreEqual(countBefore + 1, countAfter);

}

}

Проверьте, что нет в БД пользователя с таким email.

Запускаем, проверяем. Работает. Кайф! Тут понятно, какие мощности открываются. И если юнит-тестирование – это как обработка минимальных кусочков кода, а тут – это целый сценарий. Но, кстати, замечу, что MailNotify всё же высылает письма на почту. Так что перепишем его как сервис:

/LessonProject/Tools/Mail/IMailSender.cs:

public interface IMailSender

{

void SendMail(string email, string subject, string body, MailAddress mailAddress = null);

}

/LessonProject/Tools/Mail/MailSender.cs:

public class MailSender: IMailSender

{

[Inject]

public IConfig Config { get; set; }

 

private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();

 

public void SendMail(string email, string subject, string body, MailAddress mailAddress = null)

{

try

{

if (Config.EnableMail)

{

if (mailAddress == null)

{

mailAddress = new MailAddress(Config.MailSetting.SmtpReply, Config.MailSetting.SmtpUser);

}

MailMessage message = new MailMessage(

mailAddress,

new MailAddress(email))

{

Subject = subject,

BodyEncoding = Encoding.UTF8,

Body = body,

IsBodyHtml = true,

SubjectEncoding = Encoding.UTF8

};

SmtpClient client = new SmtpClient

{

Host = Config.MailSetting.SmtpServer,

Port = Config.MailSetting.SmtpPort,

UseDefaultCredentials = false,

EnableSsl = Config.MailSetting.EnableSsl,

Credentials =

new NetworkCredential(Config.MailSetting.SmtpUserName,

Config.MailSetting.SmtpPassword),

DeliveryMethod = SmtpDeliveryMethod.Network

};

client.Send(message);

}

else

{

logger.Debug(" Email: {0} {1} \t Subject: {2} {3} Body: {4}", email, Environment.NewLine, subject, Environment.NewLine, body);

}

}

catch (Exception ex)

{

logger.Error(" Mail send exception", ex.Message);

}

}

}


 

/LessonProject/Tools/Mail/NotifyMail.cs:

public static class NotifyMail

{

private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();

 

private static IConfig _config;

 

public static IConfig Config

{

get

{

if (_config == null)

{

_config = (DependencyResolver.Current).GetService< IConfig> ();

 

}

return _config;

}

}

 

private static IMailSender _mailSender;

 

public static IMailSender MailSender

{

get

{

if (_mailSender == null)

{

_mailSender = (DependencyResolver.Current).GetService< IMailSender> ();

 

}

return _mailSender;

}

}

 

public static void SendNotify(string templateName, string email,

Func< string, string> subject,

Func< string, string> body)

{

var template = Config.MailTemplates.FirstOrDefault(p => string.Compare(p.Name, templateName, true) == 0);

if (template == null)

{

logger.Error(" Can't find template (" + templateName + ")");

}

else

{

MailSender.SendMail(email,

subject.Invoke(template.Subject),

body.Invoke(template.Template));

}

}

}

/LessonProject/App_Start/NinjectWebCommon.cs:

private static void RegisterServices(IKernel kernel)

{…

kernel.Bind< IMailSender> ().To< MailSender> ();

}


 

Ну и в LessonProject.UnitTest добавим MockMailSender (/Mock/Mail/MockMailSender.cs):

public class MockMailSender: Mock< IMailSender>

{

public MockMailSender(MockBehavior mockBehavior = MockBehavior.Strict)

: base(mockBehavior)

{

this.Setup(p => p.SendMail(It.IsAny< string> (), It.IsAny< string> (), It.IsAny< string> (), It.IsAny< MailAddress> ()))

.Callback((string email, string subject, string body, MailAddress address) =>

Console.WriteLine(String.Format(" Send mock email to: {0}, subject {1}", email, subject)));

}

}

В UnitTestSetupFixture.cs (/LessonProject.UnitTest/Setup/UnitTestSetupFixture.cs):

protected virtual IKernel InitKernel()

{

kernel.Bind< MockMailSender> ().To< MockMailSender> ();

kernel.Bind< IMailSender> ().ToMethod(p => kernel.Get< MockMailSender> ().Object);

return kernel;

}

Запускаем, тесты пройдены, но на почту уже ничего не отправляется.

===============

=====START=====

===============

Create DB = LessonProject_20130314_104218

Send mock email to: chernikov@googlemail.com, subject Регистрация на

 

===============

=====BYE! ======

===============

 






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.