ASP.NET MVC Урок 1-F / ASP.NET MVC Урок E
.pdfкод в SqlRepository. Для этого мы через Web.config находим базу (она должна располагаться локально), дублировать ее, подключаться к дубликату БД, проходить тесты и в конце, удалять дубликат БД.
Создаем проект LessonProject.IntegrationTest в папке Test. Добавляем Ninject, Moq и NUnit:
,QVWDOO 3DFNDJH 1LQMHFW
,QVWDOO 3DFNDJH 0RT
,QVWDOO 3DFNDJH 18QLW
Так же создаем папку Sandbox и в Setup наследуем UnitTestSetupFixture (/Setup/IntegrationTestSetupFixture.cs) и функцию по копированию БД:
>6HW8S)L[WXUH@
SXEOLF FODVV ,QWHJUDWLRQ7HVW6HWXS)L[WXUH 8QLW7HVW6HWXS)L[WXUH
^
SXEOLF FODVV )LOH/LVW5HVWRUH
^
SXEOLF VWULQJ/RJLFDO1DPH ^JHW VHW`
SXEOLF VWULQJ7\SH ^JHW VHW`
`
SURWHFWHG VWDWLF VWULQJ1DPH'E /HVVRQ3URMHFW
SURWHFWHG VWDWLF VWULQJ7HVW'E1DPH
SULYDWH YRLG &RS\'E6WDQGDUG.HUQHO NHUQHORXW)LOH,QIR VDQGER[)LOHRXW VWULQJFRQ QHFWLRQ6WULQJ
^
YDUFRQILJ NHUQHO *HW ,&RQILJ!
YDUGE QHZ'DWD&RQWH[W FRQILJ &RQQHFWLRQ6WULQJV&RQQHFWLRQ6WULQJ
7HVW'E1DPH VWULQJ)RUPDW^ `B^ `1DPH'E 'DWH7LPH 1RZ 7R6WULQJ\\\\00GGB+ +PPVV
&RQVROH :ULWH/LQH&UHDWH '% 7HVW'E1DPH
VDQGER[)LOH QHZ)LOH,QIRVWULQJ)RUPDW^ `??^ ` EDN6DQGER[ 7HVW'E1DPH
YDUVDQGER['LU QHZ'LUHFWRU\,QIR 6DQGER[
EDFNXS)LOH
YDUWH[W%DFN8S VWULQJ)RUPDW# %DFNXS WKH GDWDEDVH
%$&.83 '$7$%$6( >^ `@
72 ',6. ^ `
:,7+ &23<B21/<
1DPH'E VDQGER[)LOH )XOO1DPH
GE ([HFXWH&RPPDQG WH[W%DFN8S
YDUUHVWRUH)LOH/LVW VWULQJ)RUPDW5(6725( ),/(/,6721/< )520 ',6. ^ `V DQGER[)LOH )XOO1DPH
YDUILOH/LVW5HVWRUHV GE ([HFXWH4XHU\ )LOH/LVW5HVWRUH! UHVWRUH)LOH/LVW 7R/LV W
YDUORJLFDO'E1DPH ILOH/LVW5HVWRUHV )LUVW2U'HIDXOW S ! S 7\SH '
YDUORJLFDO/RJ'E1DPH ILOH/LVW5HVWRUHV )LUVW2U'HIDXOW S ! S 7\SH /
YDUUHVWRUH'E VWULQJ)RUPDW5(6725( '$7$%$6( >^ `@ )520 ',6. ^ ` :,7+ ), /( 029( 1 ^ ` 72 1 ^ `??^ ` PGI 029( 1 ^ ` 72 1 ^ `??^ ` OGI 1281/2$' 67$767HVW'E1DPH VDQGER[)LOH )XOO1DPH ORJLFDO'E1DPH /RJLFDO1DPH ORJLFDO/RJ'E1DPH /RJLFDO1D PH VDQGER['LU )XOO1DPH
GE ([HFXWH&RPPDQG UHVWRUH'E
FRQQHFWLRQ6WULQJ FRQILJ &RQQHFWLRQ6WULQJV&RQQHFWLRQ6WULQJ5HSODFH 1DPH'E 7HVW'E1DPH
`
`
По порядку: В строках
YDUFRQILJ NHUQHO *HW ,&RQILJ!
YDUGE QHZ'DWD&RQWH[W FRQILJ &RQQHFWLRQ6WULQJV&RQQHFWLRQ6WULQJ
— получаем подключение к БД.
7HVW'E1DPH VWULQJ)RUPDW^ `B^ `1DPH'E 'DWH7LPH 1RZ 7R6WULQJ\\\\00GGB++PPVV
Создаем наименование тестовой БД.
EDFNXS)LOH
YDUWH[W%DFN8S VWULQJ)RUPDW# %DFNXS WKH GDWDEDVH
%$&.83 '$7$%$6( >^ `@
72 ',6. ^ `
:,7+ &23<B21/<
1DPH'E VDQGER[)LOH )XOO1DPH
GE ([HFXWH&RPPDQG WH[W%DFN8S
— выполняем бекап БД в папку Sandbox.
YDUUHVWRUH)LOH/LVW VWULQJ)RUPDW5(6725( ),/(/,6721/< )520 ',6. ^ `V
DQGER[)LOH )XOO1DPH
YDUILOH/LVW5HVWRUHV GE ([HFXWH4XHU\ )LOH/LVW5HVWRUH! UHVWRUH)LOH/LVW 7R/LV
W
YDUORJLFDO'E1DPH ILOH/LVW5HVWRUHV )LUVW2U'HIDXOW S ! S 7\SH '
YDUORJLFDO/RJ'E1DPH ILOH/LVW5HVWRUHV )LUVW2U'HIDXOW S ! S 7\SH /
— получаем логическое имя БД и файла логов, используя приведение к классу
FIleListRestore.
YDUUHVWRUH'E VWULQJ)RUPDW5(6725( '$7$%$6( >^ `@ )520 ',6. ^ ` :,7+ ),
/( 029( 1 ^ ` 72 1 ^ `??^ ` PGI 029( 1 ^ ` 72 1 ^ `??^ ` OGI 1281/2$' 67$76
7HVW'E1DPH VDQGER[)LOH )XOO1DPH ORJLFDO'E1DPH /RJLFDO1DPH ORJLFDO/RJ'E1DPH /RJLFDO1D
PH VDQGER['LU )XOO1DPH
GE ([HFXWH&RPPDQG UHVWRUH'E
— восстанавливаем БД под другим именем (TestDbName)
FRQQHFWLRQ6WULQJ FRQILJ &RQQHFWLRQ6WULQJV&RQQHFWLRQ6WULQJ5HSODFH 1DPH'E 7HVW'E1DP
H
— меняем connectionString.
И теперь можем спокойно проинициализировать IRepository к SqlRepository:
SURWHFWHG RYHUULGH YRLG ,QLW5HSRVLWRU\6WDQGDUG.HUQHO NHUQHO
^
)LOH,QIR VDQGER[)LOH
VWULQJFRQQHFWLRQ6WULQJ
&RS\'E NHUQHORXWVDQGER[)LOHRXWFRQQHFWLRQ6WULQJ
NHUQHO %LQG ZHE7HPSODWH'E'DWD&RQWH[W! 7R0HWKRG F !QHZZHE7HPSODWH'E'DWD&RQ
WH[W FRQQHFWLRQ6WULQJ
NHUQHO %LQG ,5HSRVLWRU\! 7R 6TO5HSRVLWRU\! ,Q7UDQVLHQW6FRSH
VDQGER[)LOH 'HOHWH
`
Итак, у нас есть sandboxFile – это файл бекапа, и connectionString – это новая строка подключения (к дубликату БД). Мы копируем БД, связываем именно с SqlRepository, но базу подсовываем не основную. И с ней можно делать всё что угодно. Файл бекапа базы в конце удаляем.
И дописываем уже удаление тестовой БД, после прогона всех тестов:
SULYDWH YRLG 5HPRYH'E
^
YDUFRQILJ 'HSHQGHQF\5HVROYHU &XUUHQW *HW6HUYLFH ,&RQILJ!
YDUGE QHZ'DWD&RQWH[W FRQILJ &RQQHFWLRQ6WULQJV&RQQHFWLRQ6WULQJ
YDUWH[W&ORVH&RQQHFWLRQ7HVW'E VWULQJ)RUPDW#$/7(5 '$7$%$6( >^ `@ 6(7 6,1*/ (B86(5 :,7+ 52//%$&. ,00(',$7(7HVW'E1DPH
GE ([HFXWH&RPPDQG WH[W&ORVH&RQQHFWLRQ7HVW'E
YDUWH[W'URS7HVW'E VWULQJ)RUPDW# '523 '$7$%$6( >^ `@7HVW'E1DPH
GE ([HFXWH&RPPDQG WH[W'URS7HVW'E
`
Используя TestDbName, закрываем подключение (а то оно активное), и удаляем базу данных.
Не забываем сделать копию Web.config:
[FRS\ 6ROXWLRQ'LU /HVVRQ3URMHFW?:HE FRQILJ 3URMHFW'LU 6DQGER[? \
Но кстати, иногда БД нет необходимости удалять. Например, мы хотим заполнить базу кучей данных автоматически, чтобы проверить поиск или пейджинг. Это мы рассмотрим ниже. А сейчас тест – реальное создание в БД записи:
>7HVW)L[WXUH@
SXEOLF FODVV 'HIDXOW8VHU&RQWUROOHU7HVW
^
>7HVW@
SXEOLF YRLG &UHDWH8VHUB&UHDWH1RUPDO8VHUB&RXQW3OXV2QH
^
YDUUHSRVLWRU\ 'HSHQGHQF\5HVROYHU &XUUHQW *HW6HUYLFH ,5HSRVLWRU\!
YDUFRQWUROOHU 'HSHQGHQF\5HVROYHU &XUUHQW *HW6HUYLFH /HVVRQ3URMHFW$UHDV 'HID XOW &RQWUROOHUV 8VHU&RQWUROOHU!
YDUFRXQW%HIRUH UHSRVLWRU\ 8VHUV &RXQW
YDUKWWS&RQWH[W QHZ0RFN+WWS&RQWH[W 2EMHFW
YDUURXWH QHZ5RXWH'DWD
URXWH 9DOXHV$GGFRQWUROOHU 8VHU
URXWH 9DOXHV$GGDFWLRQ 5HJLVWHU
URXWH 9DOXHV$GGDUHD 'HIDXOW
&RQWUROOHU&RQWH[W FRQWH[W QHZ&RQWUROOHU&RQWH[WQHZ5HTXHVW&RQWH[W KWWS&RQWH[ W URXWH FRQWUROOHU
FRQWUROOHU &RQWUROOHU&RQWH[W FRQWH[W
FRQWUROOHU 6HVVLRQ$GG &DSWFKD,PDJH &DSWFKD9DOXH.H\
YDUUHJLVWHU8VHU9LHZ QHZ8VHU9LHZ
^
,'
(PDLO UROOLQ[#JPDLO FRP
3DVVZRUG
&RQILUP3DVVZRUG
&DSWFKD
%LUWKGDWH'D\
%LUWKGDWH0RQWK
%LUWKGDWH<HDU
`
9DOLGDWRU 9DOLGDWH2EMHFW 8VHU9LHZ! UHJLVWHU8VHU9LHZ
FRQWUROOHU 5HJLVWHU UHJLVWHU8VHU9LHZ
YDUFRXQW$IWHU UHSRVLWRU\ 8VHUV &RXQW
$VVHUW$UH(TXDO FRXQW%HIRUH FRXQW$IWHU
`
`
Проверьте, что нет в БД пользователя с таким email.
Запускаем, проверяем. Работает. Кайф! Тут понятно, какие мощности открываются. И если юниттестирование – это как обработка минимальных кусочков кода, а тут – это целый сценарий. Но, кстати, замечу, что MailNotify всё же высылает письма на почту. Так что перепишем его как сервис:
/LessonProject/Tools/Mail/IMailSender.cs:
SXEOLF LQWHUIDFH ,0DLO6HQGHU
^
YRLG 6HQG0DLO VWULQJHPDLOVWULQJVXEMHFWVWULQJERG\ 0DLO$GGUHVV PDLO$GGUHVV
QXOO
`
/LessonProject/Tools/Mail/MailSender.cs:
SXEOLF FODVV 0DLO6HQGHU ,0DLO6HQGHU
^
>,QMHFW@
SXEOLF,&RQILJ &RQILJ ^JHW VHW`
SULYDWH VWDWLF1/RJ /RJJHU ORJJHU 1/RJ /RJ0DQDJHU *HW&XUUHQW&ODVV/RJJHU
SXEOLF YRLG 6HQG0DLO VWULQJHPDLOVWULQJVXEMHFWVWULQJERG\ 0DLO$GGUHVV PDLO$GG UHVV QXOO
^
WU\
^
LI&RQILJ (QDEOH0DLO
^
LIPDLO$GGUHVV QXOO
^
PDLO$GGUHVV QHZ0DLO$GGUHVV &RQILJ 0DLO6HWWLQJ 6PWS5HSO\ &RQIL J 0DLO6HWWLQJ 6PWS8VHU
`
0DLO0HVVDJH PHVVDJH QHZ0DLO0HVVDJH
PDLO$GGUHVV
QHZ0DLO$GGUHVV HPDLO
^
6XEMHFW VXEMHFW
%RG\(QFRGLQJ (QFRGLQJ 87)
%RG\ ERG\
,V%RG\+WPO WUXH
6XEMHFW(QFRGLQJ (QFRGLQJ 87)
`
6PWS&OLHQW FOLHQW QHZ6PWS&OLHQW
^
+RVW &RQILJ 0DLO6HWWLQJ 6PWS6HUYHU
3RUW &RQILJ 0DLO6HWWLQJ 6PWS3RUW
8VH'HIDXOW&UHGHQWLDOV IDOVH
(QDEOH6VO &RQILJ 0DLO6HWWLQJ (QDEOH6VO
&UHGHQWLDOV
QHZ1HWZRUN&UHGHQWLDO &RQILJ 0DLO6HWWLQJ 6PWS8VHU1DPH
&RQILJ 0DLO6HWWLQJ 6PWS3DVVZRUG
'HOLYHU\0HWKRG 6PWS'HOLYHU\0HWKRG 1HWZRUN
`
FOLHQW 6HQG PHVVDJH
`
HOVH
^
ORJJHU 'HEXJ(PDLO ^ ` ^ ` ?W 6XEMHFW ^ ` ^ ` %RG\ ^ `HPDLO (Q YLURQPHQW 1HZ/LQH VXEMHFW (QYLURQPHQW 1HZ/LQH ERG\
`
`
FDWFK([FHSWLRQ H[
^
ORJJHU (UURU0DLO VHQG H[FHSWLRQH[ 0HVVDJH
`
`
`
/LessonProject/Tools/Mail/NotifyMail.cs:
SXEOLF VWDWLF FODVV 1RWLI\0DLO
^
SULYDWH VWDWLF1/RJ /RJJHU ORJJHU 1/RJ /RJ0DQDJHU *HW&XUUHQW&ODVV/RJJHU
SULYDWH VWDWLF,&RQILJ BFRQILJ
SXEOLF VWDWLF,&RQILJ &RQILJ
^
JHW
^
LIBFRQILJ QXOO
^
BFRQILJ 'HSHQGHQF\5HVROYHU &XUUHQW *HW6HUYLFH ,&RQILJ!
`
UHWXUQBFRQILJ
`
`
SULYDWH VWDWLF,0DLO6HQGHU BPDLO6HQGHU
SXEOLF VWDWLF,0DLO6HQGHU 0DLO6HQGHU
^
JHW
^
LIBPDLO6HQGHU QXOO
^
BPDLO6HQGHU 'HSHQGHQF\5HVROYHU &XUUHQW *HW6HUYLFH ,0DLO6HQGHU!
`
UHWXUQBPDLO6HQGHU
`
`
SXEOLF VWDWLF YRLG 6HQG1RWLI\ VWULQJWHPSODWH1DPHVWULQJHPDLO
)XQFVWULQJ VWULQJ! VXEMHFW
)XQFVWULQJ VWULQJ! ERG\
^
YDUWHPSODWH &RQILJ 0DLO7HPSODWHV )LUVW2U'HIDXOW S !VWULQJ&RPSDUH S 1DPH WHPSODWH1DPHWUXH
LIWHPSODWH QXOO
^
ORJJHU (UURU&DQ W ILQG WHPSODWHWHPSODWH1DPH
`
HOVH
^
0DLO6HQGHU 6HQG0DLO HPDLO
VXEMHFW ,QYRNH WHPSODWH 6XEMHFW
ERG\ ,QYRNH WHPSODWH 7HPSODWH
`
`
`
/LessonProject/App_Start/NinjectWebCommon.cs:
SULYDWH VWDWLF YRLG 5HJLVWHU6HUYLFHV,.HUQHO NHUQHO
^«
NHUQHO %LQG ,0DLO6HQGHU! 7R 0DLO6HQGHU!
`
Ну и в LessonProject.UnitTest добавим MockMailSender (/Mock/Mail/MockMailSender.cs):
SXEOLF FODVV 0RFN0DLO6HQGHU 0RFN ,0DLO6HQGHU!
^
SXEOLF 0RFN0DLO6HQGHU0RFN%HKDYLRU PRFN%HKDYLRU 0RFN%HKDYLRU 6WULFW
EDVHPRFN%HKDYLRU
^
WKLV6HWXS S ! S 6HQG0DLO ,W ,V$Q\VWULQJ! ,W ,V$Q\VWULQJ! ,W ,V$Q\VWU LQJ! ,W ,V$Q\ 0DLO$GGUHVV!
&DOOEDFNVWULQJHPDLOVWULQJVXEMHFWVWULQJERG\ 0DLO$GGUHVV DGGUHVV
!
&RQVROH :ULWH/LQH 6WULQJ )RUPDW6HQG PRFN HPDLO WR ^ ` VXEMHFW ^ `HPD LO VXEMHFW
`
`
В UnitTestSetupFixture.cs (/LessonProject.UnitTest/Setup/UnitTestSetupFixture.cs):
SURWHFWHG YLUWXDO,.HUQHO,QLW.HUQHO
^
«
NHUQHO %LQG 0RFN0DLO6HQGHU! 7R 0RFN0DLO6HQGHU!
NHUQHO %LQG ,0DLO6HQGHU! 7R0HWKRG S ! NHUQHO *HW 0RFN0DLO6HQGHU! 2EMHFW
UHWXUQNHUQHO
`
Запускаем, тесты пройдены, но на почту уже ничего не отправляется.
67$57
&UHDWH '% /HVVRQ3URMHFWB B 6HQG PRFN HPDLO WR FKHUQLNRY#JRRJOHPDLO FRP VXEMHFW Ɋɟɝɢɫɬɪɚɰɢɹ ɧɚ
%<(
Генерация данных
Кроме всего прочего, мы можем и не удалять базу данных после пробегов теста. (переписать)Я добавлю GenerateData проект в папку Test, но подробно рассматривать мы его не будем, просто чтобы был. Он достаточно тривиальный. Суть его – есть некоторые наименования, и мы используем их для генерации. Например, для генерации фамилии используются фамилии американских президентов (зная их, мы сразу отличаем их от других фамилий, которые скорее будут реальными).
Это также в будущем позволяет избежать «эффекта рыбы», когда в шаблоне тестовые данные были одной определенной, но не максимальной длины и шаблон выглядел прилично, но при использовании реальных данных всё поехало.
Создадим 100 пользователей и потом посмотрим на них:
>7HVW@
SXEOLF YRLG &UHDWH8VHUB&UHDWH 8VHUVB1R$VVHUW
^
YDUUHSRVLWRU\ 'HSHQGHQF\5HVROYHU &XUUHQW *HW6HUYLFH ,5HSRVLWRU\!
YDUFRQWUROOHU 'HSHQGHQF\5HVROYHU &XUUHQW *HW6HUYLFH /HVVRQ3URMHFW$UHDV 'HID XOW &RQWUROOHUV 8VHU&RQWUROOHU!
YDUKWWS&RQWH[W QHZ0RFN+WWS&RQWH[W 2EMHFW
YDUURXWH QHZ5RXWH'DWD
URXWH 9DOXHV$GGFRQWUROOHU 8VHU
URXWH 9DOXHV$GGDFWLRQ 5HJLVWHU
URXWH 9DOXHV$GGDUHD 'HIDXOW
&RQWUROOHU&RQWH[W FRQWH[W QHZ&RQWUROOHU&RQWH[WQHZ5HTXHVW&RQWH[W KWWS&RQWH[ W URXWH FRQWUROOHU
FRQWUROOHU &RQWUROOHU&RQWH[W FRQWH[W
FRQWUROOHU 6HVVLRQ$GG &DSWFKD,PDJH &DSWFKD9DOXH.H\
YDUUDQG QHZ5DQGRPLQW'DWH7LPH 1RZ 7LFNV
IRU LQWL L L
^
YDUUHJLVWHU8VHU9LHZ QHZ8VHU9LHZ
^
,'
(PDLO (PDLO *HW5DQGRP 1DPH *HW5DQGRP 6XUQDPH *HW5DQGRP
3DVVZRUG
&RQILUP3DVVZRUG
&DSWFKD
%LUWKGDWH'D\ UDQG 1H[W
%LUWKGDWH0RQWK UDQG 1H[W
%LUWKGDWH<HDU UDQG 1H[W
`
FRQWUROOHU 5HJLVWHU UHJLVWHU8VHU9LHZ
`
`
В IntegrationTestSetupFixture.cs отключим удаление БД после работы
(/Setup/IntegrationTestSetupFixture.cs):
SURWHFWHG VWDWLF ERROUHPRYH'E$IWHU IDOVH
В Web.config установим соединение с тестовой БД:
DGG QDPH &RQQHFWLRQ6WULQJFRQQHFWLRQ6WULQJ 'DWD 6RXUFH 6$7851 3& ,QLWLDO &DWDORJ /HVVRQ
3URMHFWB B ,QWHJUDWHG 6HFXULW\ 7UXH 3RROLQJ )DOVHSURYLGHU1DPH 6\VWHP 'DWD 6
TO&OLHQW!
И запустим сайт: