{"id":176137,"date":"2013-04-09T22:54:10","date_gmt":"2013-04-09T18:54:10","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=176137"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=176137","title":{"rendered":"<span class=\"post_title\">ASP.NET MVC \u0423\u0440\u043e\u043a E. \u0422\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435<\/span>"},"content":{"rendered":"<div class=\"content html_format\">   \t<b>\u0426\u0435\u043b\u044c \u0443\u0440\u043e\u043a\u0430.<\/b> \u041d\u0430\u0443\u0447\u0438\u0442\u044c\u0441\u044f \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0442\u0435\u0441\u0442\u044b \u0434\u043b\u044f \u043a\u043e\u0434\u0430. NUnit. \u041f\u0440\u0438\u043d\u0446\u0438\u043f \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f TDD. Mock. \u042e\u043d\u0438\u0442-\u0442\u0435\u0441\u0442\u044b. \u0418\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435. \u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<h5>\u0422\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435, \u043f\u0440\u0438\u043d\u0446\u0438\u043f TDD, \u044e\u043d\u0438\u0442-\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u043f\u0440\u043e\u0447\u0435\u0435.<\/h5>\n<p>  \u0422\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0434\u043b\u044f \u043c\u0435\u043d\u044f \u043b\u0438\u0447\u043d\u043e \u2013 \u044d\u0442\u043e \u0442\u0435\u043c\u0430 \u043c\u043d\u043e\u0433\u0438\u0445 \u0440\u0430\u0437\u043c\u044b\u0448\u043b\u0435\u043d\u0438\u0439. \u041d\u0443\u0436\u043d\u044b \u0438\u043b\u0438 \u043d\u0435 \u043d\u0443\u0436\u043d\u044b \u0442\u0435\u0441\u0442\u044b? \u041d\u043e \u043d\u0438\u043a\u0442\u043e \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0441\u043f\u043e\u0440\u0438\u0442\u044c, \u0447\u0442\u043e \u0434\u043b\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0442\u0435\u0441\u0442\u043e\u0432 \u043d\u0443\u0436\u043d\u044b \u0440\u0435\u0441\u0443\u0440\u0441\u044b. <br \/>  \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0434\u0432\u0430 \u0441\u043b\u0443\u0447\u0430\u044f:  <\/p>\n<ol>\n<li>\u041c\u044b \u0434\u0435\u043b\u0430\u0435\u043c \u0441\u0430\u0439\u0442, \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0437\u0430\u043a\u0430\u0437\u0447\u0438\u043a\u0443, \u043e\u043d \u0432\u044b\u0441\u044b\u043b\u0430\u0435\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u043d\u0435\u0442\u043e\u0447\u043d\u043e\u0441\u0442\u0435\u0439 \u0438 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043f\u043e\u0436\u0435\u043b\u0430\u043d\u0438\u0439, \u043c\u044b \u0438\u0445 \u0431\u043e\u0434\u0440\u043e \u043f\u0440\u0430\u0432\u0438\u043c \u0438 \u0441\u0430\u0439\u0442 \u043e\u0442\u0434\u0430\u0435\u043c \u0437\u0430\u043a\u0430\u0437\u0447\u0438\u043a\u0443, \u0442.\u0435. \u0432\u044b\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u043c \u043d\u0430 \u0435\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440. \u041d\u0430 \u0435\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440 \u043d\u0438\u043a\u0442\u043e \u043d\u0435 \u0445\u043e\u0434\u0438\u0442, \u0437\u0430\u043a\u0430\u0437\u0447\u0438\u043a \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u0442, \u0447\u0442\u043e \u0447\u0443\u0434\u0430 \u043d\u0435 \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u043e \u0438 \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u0435\u0442 \u043f\u043b\u0430\u0442\u0438\u0442\u044c \u0437\u0430 \u0445\u043e\u0441\u0442\u0438\u043d\u0433\/\u0434\u043e\u043c\u0435\u043d. \u0421\u0430\u0439\u0442 \u0443\u043c\u0438\u0440\u0430\u0435\u0442. \u041d\u0443\u0436\u043d\u044b \u043b\u0438 \u0442\u0430\u043c \u0442\u0435\u0441\u0442\u044b?<\/li>\n<li>\u041c\u044b \u0434\u0435\u043b\u0430\u0435\u043c \u0441\u0430\u0439\u0442, \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0437\u0430\u043a\u0430\u0437\u0447\u0438\u043a\u0443, \u043e\u043d \u0432\u044b\u0441\u044b\u043b\u0430\u0435\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u043f\u0440\u0430\u0432\u043e\u043a, \u043c\u044b \u0438\u0445 \u0431\u043e\u0434\u0440\u043e \u043f\u0440\u0430\u0432\u0438\u043c, \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0441\u0430\u0439\u0442. \u0427\u0435\u0440\u0435\u0437 \u043f\u043e\u043b\u0433\u043e\u0434\u0430 \u043d\u0430 \u0441\u0430\u0439\u0442\u0435 300 \u0443\u043d\u0438\u043a\u043e\u0432 \u0432 \u0434\u0435\u043d\u044c \u0438 \u044d\u0442\u0430 \u0446\u0438\u0444\u0440\u0430 \u0440\u0430\u0441\u0442\u0435\u0442 \u0438\u0437\u043e \u0434\u043d\u044f \u0432 \u0434\u0435\u043d\u044c. \u0417\u0430\u043a\u0430\u0437\u0447\u0438\u043a \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u043f\u0440\u043e\u0441\u0438\u0442 \u043d\u043e\u0432\u044b\u0435 \u0444\u0438\u0447\u0438, \u0441\u0442\u0430\u0440\u044b\u0439 \u043a\u043e\u0434 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0440\u0430\u0437\u0440\u0430\u0441\u0442\u0430\u0442\u044c\u0441\u044f, \u0438 \u0441\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0435\u043c \u0435\u0433\u043e \u0432\u0441\u0451 \u0441\u043b\u043e\u0436\u043d\u0435\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c. <\/li>\n<\/ol>\n<p>  <a name=\"habracut\"><\/a><\/p>\n<p>  \u0412\u0438\u0434\u0438\u0442\u0435 \u043b\u0438, \u0442\u0443\u0442 \u0434\u0438\u043b\u0435\u043c\u043c\u0430 \u0442\u0430\u043a\u043e\u0432\u0430, \u0447\u0442\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0441\u0430\u0439\u0442\u0430 \u043d\u0435\u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0443\u0435\u043c\u044b\u0439. \u0423 \u043c\u0435\u043d\u044f \u0431\u044b\u043b\u043e \u0438 \u0442\u0430\u043a, \u0447\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u043d\u043d\u044b\u0439 \u043d\u0430 \u043a\u043e\u043b\u0435\u043d\u043a\u0435 \u0441\u0430\u0439\u0442 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b\u0441\u044f \u0432\u0435\u0441\u044c\u043c\u0430 \u0431\u043e\u0434\u0440\u043e, \u0430 \u0431\u044b\u0432\u0430\u043b\u043e, \u0447\u0442\u043e \u043a\u0440\u0443\u0442\u0443\u044e \u0440\u0430\u0431\u043e\u0442\u0443 \u0437\u0430\u043a\u0430\u0437\u0447\u0438\u043a \u043e\u043f\u043b\u0430\u0442\u0438\u043b, \u043d\u043e \u0434\u0430\u0436\u0435 \u043d\u0435 \u043f\u0440\u0438\u043d\u044f\u043b. \u0418\u0442\u0430\u043a, \u0442\u0430\u043a\u0442\u0438\u043a\u0430 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0442\u0430\u043a\u043e\u0439:  <\/p>\n<ul>\n<li>\u041f\u0438\u0441\u0430\u0442\u044c \u0442\u0435\u0441\u0442\u044b \u0432\u0441\u0435\u0433\u0434\u0430. \u041c\u044b \u043a\u0440\u0443\u0442\u0430\u044f \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044f, \u043c\u044b \u043f\u043e\u043a\u0440\u044b\u0432\u0430\u0435\u043c 90% \u043a\u043e\u0434\u0430 \u0432\u0441\u044f\u0447\u0435\u0441\u043a\u0438\u043c\u0438 \u0442\u0435\u0441\u0442\u0430\u043c\u0438, \u0438 \u043d\u0430\u043c \u0440\u0435\u0430\u043b\u044c\u043d\u043e \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e, \u0447\u0442\u043e \u043c\u044b \u0442\u0440\u0430\u0442\u0438\u043c \u043d\u0430 \u044d\u0442\u043e \u0432 100500 \u0440\u0430\u0437 \u0431\u043e\u043b\u044c\u0448\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u0438\/\u0434\u0435\u043d\u0435\u0433, \u0432\u0435\u0434\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0443\u0435\u043c \u0438 \u043c\u044b \u0432\u043e\u043e\u0431\u0449\u0435 \u043a\u0440\u0430\u0441\u0430\u0432\u0446\u044b.<\/li>\n<li>\u041d\u0435 \u043f\u0438\u0441\u0430\u0442\u044c \u0442\u0435\u0441\u0442\u044b \u043d\u0438\u043a\u043e\u0433\u0434\u0430. \u041c\u044b \u043a\u0440\u0443\u0442\u0430\u044f \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044f, \u043c\u044b \u043d\u0430\u0441\u0442\u043e\u043b\u044c\u043a\u043e \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c, \u0447\u0442\u043e \u043c\u043e\u0436\u0435\u043c \u0432 \u0443\u043c\u0435 \u043f\u0435\u0440\u0435\u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0432\u0435\u0441\u044c \u043f\u0440\u043e\u0435\u043a\u0442, \u0438 \u0435\u0441\u043b\u0438 \u043d\u0430\u0448 \u043a\u043e\u0434 \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u0442\u0441\u044f, \u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442, \u0447\u0442\u043e \u043e\u043d \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0440\u0430\u0431\u043e\u0447\u0438\u0439. \u0415\u0441\u043b\u0438 \u0447\u0442\u043e-\u0442\u043e \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u0442\u043e \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e \u044d\u0442\u043e \u0445\u043e\u0441\u0442\u0438\u043d\u0433, \u0438\u043b\u0438 \u043e\u0448\u0438\u0431\u043a\u0430 \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435. \u0438\u043b\u0438 \u0444\u0438\u0447\u0430 \u0442\u0430\u043a\u0430\u044f.<\/li>\n<li>\u041f\u0438\u0441\u0430\u0442\u044c \u0442\u0435\u0441\u0442\u044b, \u043d\u043e \u043d\u0435 \u0432\u0441\u0435\u0433\u0434\u0430. \u0422\u0443\u0442 \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u043e\u043d\u044f\u0442\u044c, \u0447\u0442\u043e \u043a\u0430\u043a\u0438\u043c \u0431\u044b \u043d\u0438 \u0431\u044b\u043b \u0441\u0430\u0439\u0442 \u0438\u043b\u0438 \u043f\u0440\u043e\u0435\u043a\u0442, \u0442\u043e \u043e\u043d \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430. \u0410 \u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442, \u0447\u0442\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u0432\u0441\u044f\u0447\u0435\u0441\u043a\u0438\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438, \u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0432\u0430\u0436\u043d\u044b\u0435, \u044f \u0431\u044b \u0434\u0430\u0436\u0435 \u0441\u043a\u0430\u0437\u0430\u043b \u2014 \u043a\u0440\u0438\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435, \u043a\u0430\u043a-\u0442\u043e \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u0441\u0430\u0439\u0442\u0435, \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0437\u0430\u043a\u0430\u0437, \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u043e\u0441\u0442\u044c \u0438\u043b\u0438 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439. \u041d\u0435\u043f\u0440\u0438\u044f\u0442\u043d\u043e, \u043a\u043e\u0433\u0434\u0430 \u0445\u043e\u0447\u0435\u0448\u044c, \u0430 \u043d\u0435 \u043c\u043e\u0436\u0435\u0448\u044c \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f, \u0432\u0435\u0434\u044c \u0441\u0430\u0439\u0442-\u0442\u043e \u043d\u0443\u0436\u043d\u044b\u0439. <\/li>\n<li>\u0414\u043b\u044f \u0447\u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0442\u0435\u0441\u0442\u044b? \u042d\u0442\u043e \u043a\u0430\u043a \u043f\u0440\u0438\u043d\u0446\u0438\u043f \u0432\u0435\u0434\u0435\u043d\u0438\u044f \u0434\u0432\u043e\u0439\u043d\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 \u0431\u0443\u0445\u0433\u0430\u043b\u0442\u0435\u0440\u0438\u0438. \u041a\u0430\u0436\u0434\u043e\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435, \u043a\u0430\u0436\u0434\u044b\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442\u0441\u044f \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0431\u043e\u0442\u043e\u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u044c\u044e \u0441\u0430\u0439\u0442\u0430, \u043d\u043e \u0438 \u0435\u0449\u0435 \u043a\u0430\u043a \u043c\u0438\u043d\u0438\u043c\u0443\u043c \u043e\u0434\u043d\u0438\u043c \u0442\u0435\u0441\u0442\u043e\u043c. \u041f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u043a\u043e\u0434\u0430 \u044e\u043d\u0438\u0442-\u0442\u0435\u0441\u0442\u044b \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442, \u0447\u0442\u043e \u0438\u043c\u043d\u043d\u043e \u043f\u043e\u0448\u043b\u043e \u043d\u0435 \u0442\u0430\u043a \u0438 \u043a\u0440\u0430\u0441\u043d\u044b\u043c \u043f\u043e\u0434\u0441\u0432\u0435\u0447\u0438\u0432\u0430\u044e\u0442 \u043c\u0435\u0441\u0442\u0430, \u0433\u0434\u0435 \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u043e \u043d\u0430\u0440\u0443\u0448\u0435\u043d\u0438\u0435. \u041d\u043e \u0442\u0430\u043a \u043b\u0438 \u044d\u0442\u043e? <\/li>\n<\/ul>\n<p>  \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0440\u0438\u043d\u0446\u0438\u043f TDD:  <\/p>\n<ol>\n<li>\u041f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0437\u0430\u0434\u0430\u043d\u0438\u0435 \u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0442\u0435\u0441\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0430\u0432\u0430\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f<\/li>\n<li>\u041d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043b\u044e\u0431\u043e\u0439 \u043a\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0439 \u0442\u0435\u0441\u0442 \u0438 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0442\u0435\u0441\u0442\u044b<\/li>\n<li>\u0421\u0434\u0435\u043b\u0430\u0442\u044c \u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u043d\u0433, \u0442.\u0435. \u0443\u0431\u0440\u0430\u0442\u044c \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u044e\u0449\u0438\u0439\u0441\u044f \u043a\u043e\u0434, \u0435\u0441\u043b\u0438 \u043d\u0430\u0434\u043e, \u043d\u043e \u0447\u0442\u043e\u0431\u044b \u0432\u0441\u0435 \u0442\u0435\u0441\u0442\u044b \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u043b\u0438<\/li>\n<\/ol>\n<p>\u2003<\/p>\n<p>  \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0431\u044b\u043b\u043e \u0434\u0430\u043d\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435:<\/p>\n<p>  \u041c\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 \u0431\u043b\u043e\u0433 \u043f\u043e\u043b\u0435 \u0442\u0435\u0433\u043e\u0432. \u0422\u0430\u043a \u043a\u0430\u043a \u0443 \u043d\u0430\u0441 \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043c\u043d\u043e\u0433\u043e \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0432 \u0431\u043b\u043e\u0433\u0435, \u0442\u043e \u044d\u0442\u043e \u043f\u043e\u043b\u0435 \u0440\u0435\u0448\u0438\u043b\u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u043c. \u0422\u0430\u043a \u043a\u0430\u043a \u0443\u0436\u0435 \u0435\u0441\u0442\u044c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434, \u0442\u043e \u0441\u043a\u0430\u0444\u0444\u043e\u043b\u0434\u0438\u043d\u0433\u043e\u043c \u043d\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438\u0441\u044c. \u0412\u0440\u0443\u0447\u043d\u0443\u044e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043b\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 \u2013 \u0432\u0441\u0451 \u043e\u043a. \u041f\u0440\u043e\u0433\u043d\u0430\u043b\u0438 \u0442\u0435\u0441\u0442\u044b \u2013 \u0432\u0441\u0451 \u043e\u043a. \u041d\u043e \u0437\u0430\u0431\u044b\u043b\u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044f \u0432 UpdatePost (cache.Tags = instance.Tags;). \u041f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0441\u0442\u0430\u0440\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0438 \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0442\u0435\u0433\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043d\u0435 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u044e\u0442\u0441\u044f. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0442\u0435\u0441\u0442\u044b \u043f\u0440\u043e\u0448\u043b\u0438 \u043d\u0430 \u0443\u0440\u0430. \u0416\u0438\u0437\u043d\u044c \u2014 \u0431\u043e\u043b\u044c!<\/p>\n<p>  \u0427\u0442\u043e \u0436, \u043a\u0430\u043a \u0432\u0438\u0434\u043d\u043e, \u043c\u044b \u043d\u0430\u0440\u0443\u0448\u0438\u043b\u0438 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043f\u0440\u0438\u043d\u0446\u0438\u043f TDD \u2013 \u0432\u043d\u0430\u0447\u0430\u043b\u0435 \u043f\u0438\u0448\u0438 \u0442\u0435\u0441\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0430\u0432\u0430\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f, \u0430 \u0443\u0436\u0435 \u043f\u043e\u0442\u043e\u043c \u043f\u0438\u0448\u0438 \u043a\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0435\u0433\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442. \u041d\u043e(!) \u0442\u0443\u0442 \u0435\u0441\u0442\u044c \u0438 \u0432\u0442\u043e\u0440\u0430\u044f \u0445\u0438\u0442\u0440\u043e\u0441\u0442\u044c \u2014 \u043c\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0438 \u0442\u0435\u0441\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0437\u0430\u043f\u0438\u0441\u0438 \u0431\u043b\u043e\u0433\u0430 \u0441 \u0442\u0435\u0433\u043e\u043c. \u041a\u043e\u043d\u0435\u0447\u043d\u043e, \u0441\u0440\u0430\u0437\u0443 \u0436\u0435 \u0443 \u043d\u0430\u0441 \u044d\u0442\u043e \u043d\u0435 \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043b\u043e\u0441\u044c (\u0442.\u0435. \u0442\u0435\u0441\u0442 \u043d\u0435 \u043f\u0440\u043e\u0448\u0435\u043b), \u043d\u043e \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u0432 ModelView \u0447\u0442\u043e-\u0442\u043e \u0442\u0438\u043f\u0430 throw new NotImplementedException(). \u0412\u0441\u0451 \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043b\u043e\u0441\u044c, \u0442\u0435\u0441\u0442 \u0433\u043e\u0440\u0438\u0442 \u043a\u0440\u0430\u0441\u043d\u044b\u043c, \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u044d\u0442\u043e \u043f\u043e\u043b\u0435 \u0441 \u0442\u0435\u0433\u043e\u043c, \u0443\u0431\u0438\u0440\u0430\u044f \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435, \u0442\u0435\u0441\u0442 \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442. \u0412\u0441\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0442\u0435\u0441\u0442\u044b \u0442\u043e\u0436\u0435 \u043f\u0440\u043e\u0445\u043e\u0434\u044f\u0442. \u041f\u0440\u0438\u043d\u0446\u0438\u043f\u044b \u0441\u043e\u0431\u043b\u044e\u0434\u0435\u043d\u044b, \u0430 \u043e\u0448\u0438\u0431\u043a\u0430 \u043e\u0441\u0442\u0430\u043b\u0430\u0441\u044c. <\/p>\n<p>  \u0427\u0442\u043e \u044f \u043c\u043e\u0433\u0443 \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u043f\u0440\u0438\u043d\u0446\u0438\u043f \u043d\u0430\u0439\u0434\u0435\u0442\u0441\u044f \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f, \u0433\u0434\u0435 \u043e\u043d \u043d\u0435 \u0441\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442. \u0422.\u0435. \u043d\u0435\u0442 \u0442\u0430\u043a\u043e\u0433\u043e \u2013 \u043e\u0442\u043a\u043b\u044e\u0447\u0438\u043b\u0438 \u043c\u043e\u0437\u0433\u0438 \u0438 \u043f\u043e\u0433\u043d\u0430\u043b\u0438. \u041e\u0434\u043d\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u043a\u0430\u0437\u0430\u0442\u044c \u0442\u043e\u0447\u043d\u043e, \u0438 \u044d\u0442\u043e \u0433\u043b\u0430\u0432\u043d\u044b\u0439 \u0432\u044b\u0432\u043e\u0434 \u0438\u0437 \u044d\u0442\u0438\u0445 \u0440\u0430\u0441\u0441\u0443\u0436\u0434\u0435\u043d\u0438\u0439:<br \/>  \u0442\u0435\u0441\u0442\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u0438\u0441\u0430\u0442\u044c\u0441\u044f \u0431\u044b\u0441\u0442\u0440\u043e<br \/>  \u0422\u0430\u043a \u043a\u0430\u043a\u0438\u0435 \u0436\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u043c\u044b \u0440\u0435\u0448\u0430\u0435\u043c \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u043d\u0430 \u0441\u0430\u0439\u0442\u0435:  <\/p>\n<ul>\n<li>\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 <\/li>\n<li>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 <\/li>\n<li>\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 <\/li>\n<li>\u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 <\/li>\n<li>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043f\u0440\u0430\u0432 \u043d\u0430 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435<\/li>\n<li>\u0412\u044b\u0434\u0430\u0447\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438<\/li>\n<\/ul>\n<p>  \u042d\u0442\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f. \u041a\u0430\u043a, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f:  <\/p>\n<ul>\n<li>\u041f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043f\u043e\u043b\u044f \u0434\u043b\u044f \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f<\/li>\n<li>\u041f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u043d\u0430 \u00ab\u0417\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f\u00bb \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435<\/li>\n<li>\u0415\u0441\u043b\u0438 \u0432\u0441\u0451 \u0443\u0434\u0430\u0447\u043d\u043e, \u0442\u043e \u0432\u044b\u0434\u0430\u0435\u043c \u0441\u0442\u0440\u0430\u043d\u0438\u0447\u043a\u0443 \u00ab\u041c\u043e\u043b\u043e\u0434\u0435\u0446\u00bb, \u0435\u0441\u043b\u0438 \u0436\u0435 \u043d\u0435 \u0432\u0441\u0451 \u0445\u043e\u0440\u043e\u0448\u043e, \u0442\u043e \u0432\u044b\u0434\u0430\u0435\u043c \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435 \u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u043c \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043e\u043f\u043b\u043e\u0448\u043d\u043e\u0441\u0442\u044c<\/li>\n<li>\u0415\u0441\u043b\u0438 \u0432\u0441\u0451 \u0445\u043e\u0440\u043e\u0448\u043e, \u0442\u043e \u0432 \u0411\u0414 \u0443 \u043d\u0430\u0441 \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0437\u0430\u043f\u0438\u0441\u044c <\/li>\n<li>\u0410 \u0435\u0449\u0435 \u043c\u044b \u043f\u0438\u0441\u044c\u043c\u043e \u0441 \u0430\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u0435\u0439 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c<\/li>\n<\/ul>\n<p>  \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0434\u043b\u044f \u0432\u0441\u0435\u0433\u043e \u044d\u0442\u043e\u0433\u043e \u044e\u043d\u0438\u0442-\u0442\u0435\u0441\u0442\u044b:  <\/p>\n<ul>\n<li>\u0427\u0442\u043e \u043c\u044b \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0435\u043c\u0443 \u043f\u043e\u043b\u044f \u0434\u043b\u044f \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f (\u0442.\u0435. \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u043f\u0443\u0441\u0442\u043e\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u043a\u043b\u0430\u0441\u0441\u0430 RegisterUserView)<\/li>\n<li>\u0427\u0442\u043e \u0443 \u043d\u0430\u0441 \u0441\u0442\u043e\u044f\u0442 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u0438 \u0432\u0441\u0451 \u0442\u0430\u043a\u043e\u0435, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043b\u0438 \u043c\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0432 \u0411\u0414 <\/li>\n<li>\u0427\u0442\u043e \u0432\u044b\u0434\u0430\u0435\u043c \u0438\u043c\u0435\u043d\u043d\u043e \u00ab\u041c\u043e\u043b\u043e\u0434\u0435\u0446\u00bb \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443<\/li>\n<li>\u0427\u0442\u043e \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0437\u0430\u043f\u0438\u0441\u044c, \u0447\u0442\u043e \u0431\u044b\u043b\u043e \u0434\u0432\u0435 \u0437\u0430\u043f\u0438\u0441\u0438, \u0430 \u0441\u0442\u0430\u043b\u043e \u0442\u0440\u0438 \u0437\u0430\u043f\u0438\u0441\u0438<\/li>\n<li>\u0427\u0442\u043e \u043f\u044b\u0442\u0430\u0435\u043c\u0441\u044f \u0447\u0442\u043e-\u0442\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c, \u043d\u0430\u0445\u043e\u0434\u0438\u043c \u0448\u0430\u0431\u043b\u043e\u043d \u0438 \u0432\u044b\u0437\u0432\u044b\u0432\u0430\u0435\u043c MailNotify.<\/li>\n<\/ul>\n<p>  \u041f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c, \u043f\u043e\u0436\u0430\u043b\u0443\u0439.<\/p>\n<h5>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c NUnit<\/h5>\n<p>  \u0418\u0434\u0435\u043c \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435 <a href=\"http:\/\/sourceforge.net\/projects\/nunit\/\">http:\/\/sourceforge.net\/projects\/nunit\/<\/a> \u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c NUnit. \u0422\u0430\u043a \u0436\u0435 \u0432 VS \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c NUnit Test Adapter (\u043d\u0443 \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0442\u0435\u0441\u0442\u044b \u043f\u0440\u044f\u043c\u043e \u0432 VS).<\/p>\n<p>  <img decoding=\"async\" src=\"http:\/\/habrastorage.org\/storage2\/47d\/077\/030\/47d077030a2a58e2dd6bea550a66884a.jpg\"\/><br \/>  \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043f\u0430\u043f\u043e\u0447\u043a\u0443 \u0442\u0438\u043f\u0430 Solution Folder Test \u0438 \u0432 \u043d\u0435\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043f\u0440\u043e\u0435\u043a\u0442 LessonProject.UnitTest \u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c \u0442\u0430\u043c NUnit:  <\/p>\n<pre><code class=\"bash\">Install-Package NUnit <\/code><\/pre>\n<p>  \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043a\u043b\u0430\u0441\u0441 UserControllerTest \u0432 (\/Test\/Default\/UserContoller.cs):  <\/p>\n<pre><code class=\"cs\">  [TestFixture]     public class UserControllerTest     {     } <\/code><\/pre>\n<p>  \u0418\u0442\u0430\u043a, \u043f\u0440\u0438\u043d\u0446\u0438\u043f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043d\u0430\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0442\u0435\u0441\u0442\u043e\u0432 Method_Scenario_ExpectedBehavior:  <\/p>\n<ul>\n<li>Method \u2013 \u043c\u0435\u0442\u043e\u0434 [\u0438\u043b\u0438 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e], \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0442\u0435\u0441\u0442\u0438\u0440\u0443\u0435\u043c <\/li>\n<li>Scenario \u2013 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0442\u0435\u0441\u0442\u0438\u0440\u0443\u0435\u043c<\/li>\n<li>ExpectedBehavior \u2013 \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u043e\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435<\/li>\n<\/ul>\n<p>  \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043f\u0435\u0440\u0432\u043e\u0435, \u0447\u0442\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c View c \u043a\u043b\u0430\u0441\u0441\u043e\u043c UserView \u0434\u043b\u044f \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438:  <\/p>\n<pre><code class=\"cs\"> public void Register_GetView_ItsOkViewModelIsUserView()         {             Console.WriteLine(&quot;=====INIT======&quot;);             var controller = new UserController();             Console.WriteLine(&quot;======ACT======&quot;);             var result = controller.Register();             Console.WriteLine(&quot;====ASSERT=====&quot;);             Assert.IsInstanceOf&lt;ViewResult&gt;(result);             Assert.IsInstanceOf&lt;UserView&gt;(((ViewResult)result).Model);  } <\/code><\/pre>\n<p>  \u0418\u0442\u0430\u043a, \u0432\u0441\u0435 \u0442\u0435\u0441\u0442\u044b \u0434\u0435\u043b\u044f\u0442\u0441\u044f \u043d\u0430 3 \u0447\u0430\u0441\u0442\u0438 Init-&gt;Act-&gt;Assert:  <\/p>\n<ul>\n<li>Init \u2013 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f, \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043d\u0430\u0448 UserController<\/li>\n<li>Act \u2013 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435, \u043c\u044b \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043d\u0430\u0448 controller.Register<\/li>\n<li>Assert \u2013 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430, \u0447\u0442\u043e \u0432\u0441\u0451 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0442\u0430\u043a.<\/li>\n<\/ul>\n<p>  \u041e\u0442\u043a\u0440\u043e\u0435\u043c \u0432\u043a\u043b\u0430\u0434\u043a\u0443 Test Explorer:<br \/>  <img decoding=\"async\" src=\"http:\/\/habrastorage.org\/storage2\/4d4\/145\/82d\/4d414582db14c662abd0b32458f7249f.jpg\"\/><\/p>\n<p>  \u0415\u0441\u043b\u0438 \u0430\u0434\u0430\u043f\u0442\u0435\u0440 NUnit \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0431\u044b\u043b \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d, \u0442\u043e \u043c\u044b \u0443\u0432\u0438\u0434\u0438\u043c \u043d\u0430\u0448 \u0442\u0435\u0441\u0442-\u043c\u0435\u0442\u043e\u0434. <br \/>  \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c. \u0422\u0435\u0441\u0442 \u043f\u0440\u043e\u0439\u0434\u0435\u043d, \u043c\u043e\u0436\u043d\u043e \u0438\u0434\u0442\u0438 \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0442\u044c \u0448\u0430\u043c\u043f\u0430\u043d\u0441\u043a\u043e\u0435. \u0421\u0442\u043e\u043e\u043e\u043f. \u042d\u0442\u043e \u043b\u0438\u0448\u044c \u0441\u0430\u043c\u0430\u044f \u043b\u0435\u0433\u043a\u0430\u044f \u0447\u0430\u0441\u0442\u044c, \u0430 \u043a\u0430\u043a \u0431\u044b\u0442\u044c \u0441 \u0442\u043e\u0439 \u0447\u0430\u0441\u0442\u044c\u044e, \u0433\u0434\u0435 \u043c\u044b \u0447\u0442\u043e-\u0442\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c. \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043c\u044b \u043d\u0435 \u0438\u043c\u0435\u0435\u043c \u0411\u0414, \u043d\u0430\u0448 Repositary \u2013 null, \u043d\u043e\u043b\u044c, \u043d\u0438\u0447\u0435\u0433\u043e. <br \/>  \u0418\u0437\u0443\u0447\u0438\u043c \u0442\u0435\u043f\u0435\u0440\u044c \u043a\u043b\u0430\u0441\u0441 \u0438 \u043c\u0435\u0442\u043e\u0434\u044b \u0434\u043b\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 (\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f). <b>SetUpFixture<\/b> \u2013 \u043a\u043b\u0430\u0441\u0441, \u043f\u043e\u043c\u0435\u0447\u0435\u043d\u043d\u044b\u0439 \u044d\u0442\u0438\u043c \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u043c, \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0432 \u043d\u0435\u043c \u0435\u0441\u0442\u044c \u043c\u0435\u0442\u043e\u0434\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0440\u043e\u0432\u043e\u0434\u044f\u0442 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043f\u0435\u0440\u0435\u0434 \u0442\u0435\u0441\u0442\u0430\u043c\u0438 \u0438 \u0437\u0430\u0447\u0438\u0441\u0442\u043a\u0443 \u043f\u043e\u0441\u043b\u0435 \u0442\u0435\u0441\u0442\u043e\u0432. \u042d\u0442\u043e \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0441\u044f \u043a \u043e\u0434\u043d\u043e\u043c\u0443 \u0438 \u0442\u043e\u043c\u0443 \u0436\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0443 \u0438\u043c\u0435\u043d.  <\/p>\n<ul>\n<li>Setup \u2013 \u043c\u0435\u0442\u043e\u0434, \u043f\u043e\u043c\u0435\u0447\u0435\u043d\u043d\u044b\u0439 \u044d\u0442\u0438\u043c \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u043c, \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0434\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0432\u0441\u0435\u0445 \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432. \u0415\u0441\u043b\u0438 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u043a\u043b\u0430\u0441\u0441\u0435 \u0441 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u043c TestFixture, \u0442\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0434 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435\u043c \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0442\u043e\u043b\u044c\u043a\u043e \u044d\u0442\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430.<\/li>\n<li>TearDown \u2013 \u043c\u0435\u0442\u043e\u0434, \u043f\u043e\u043c\u0435\u0447\u0435\u043d\u043d\u044b\u0439 \u044d\u0442\u0438\u043c \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u043c, \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0432\u0441\u0435\u0445 \u0442\u0435\u0441\u0442\u043e\u0432. \u0415\u0441\u043b\u0438 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u043a\u043b\u0430\u0441\u0441\u0435 \u0441 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u043c TestFixture, \u0442\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u043b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0432\u0441\u0435\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432. <\/li>\n<\/ul>\n<p>  \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043a\u043b\u0430\u0441\u0441 UnitTestSetupFixture.cs (\/Setup\/UnitTestSetupFixture.cs):   <\/p>\n<pre><code class=\"cs\">  [SetUpFixture]     public class UnitTestSetupFixture     {         [SetUp]         public void Setup()         {             Console.WriteLine(&quot;===============&quot;);             Console.WriteLine(&quot;=====START=====&quot;);             Console.WriteLine(&quot;===============&quot;);         }          [TearDown]         public void TearDown()         {             Console.WriteLine(&quot;===============&quot;);             Console.WriteLine(&quot;=====BYE!======&quot;);             Console.WriteLine(&quot;===============&quot;);         }     } <\/code><\/pre>\n<p>  \u0417\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u043c:<br \/>  <code> =============== =====START===== =============== =====INIT====== ======ACT====== ====ASSERT=====  =============== =====BYE!====== =============== <\/code><\/p>\n<h5>Mock<\/h5>\n<p>  \u0418\u0442\u0430\u043a, Mock \u2013 \u044d\u0442\u043e \u043e\u0431\u044a\u0435\u043a\u0442-\u043f\u0430\u0440\u043e\u0434\u0438\u044f. \u0422.\u0435. \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043d\u0435 \u0431\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445, \u0430 \u0447\u0442\u043e-\u0442\u043e \u043f\u043e\u0445\u043e\u0436\u0435\u0435 \u043d\u0430 \u0431\u0430\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445. \u041c\u0438\u0440\u0430\u0436, \u0432 \u043e\u0431\u0449\u0435\u043c-\u0442\u043e. \u0415\u0441\u0442\u044c \u0435\u0449\u0435 Stub \u2013 \u044d\u0442\u043e \u0437\u0430\u0433\u043b\u0443\u0448\u043a\u0430. \u041f\u0440\u0438\u043c\u0435\u0440 \u043c\u0435\u0442\u043e\u0434\u0430 \u0437\u0430\u0433\u043b\u0443\u0448\u043a\u0438:  <\/p>\n<pre><code class=\"cs\">public int GetRandom()         {             return 4;         } <\/code><\/pre>\n<p>  \u041d\u043e \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Mock:  <\/p>\n<pre><code class=\"bash\">Install-Package Moq <\/code><\/pre>\n<p>  \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c, \u043a\u0430\u043a\u043e\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435 \u0435\u0441\u0442\u044c \u0443 \u043d\u0430\u0441, \u0447\u0442\u043e\u0431\u044b \u043c\u044b \u043f\u0440\u043e\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u0434\u043b\u044f \u043d\u0435\u0433\u043e Mock-\u043e\u0431\u044a\u0435\u043a\u0442\u044b. \u0412 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0435, \u044d\u0442\u043e \u0432\u0441\u0451, \u0447\u0442\u043e \u043c\u044b \u043d\u0435\u043a\u043e\u0433\u0434\u0430 \u0432\u044b\u043d\u0435\u0441\u043b\u0438 \u0432 Ninject Kernel:  <\/p>\n<ul>\n<li>IRepository<\/li>\n<li>IConfig<\/li>\n<li>IMapper<\/li>\n<li>IAuthentication<\/li>\n<\/ul>\n<p>  \u0418 \u0442\u0443\u0442 \u044f \u0441\u0434\u0435\u043b\u0430\u044e \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u0437\u0430\u043c\u0435\u0447\u0430\u043d\u0438\u0435. \u041c\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u043c \u0432\u044b\u043d\u0435\u0441\u0442\u0438 Config \u0432 \u043e\u0431\u044a\u0435\u043a\u0442\u044b-\u043c\u0438\u0440\u0430\u0436\u0438. \u041d\u0435 \u0432 \u043f\u043b\u0430\u043d\u0435, \u0447\u0442\u043e \u044d\u0442\u043e \u0441\u043e\u0432\u0441\u0435\u043c \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0430 \u0432 \u043f\u043b\u0430\u043d\u0435 \u2013 \u0447\u0442\u043e \u044d\u0442\u043e \u043f\u043b\u043e\u0445\u0430\u044f \u0437\u0430\u0442\u0435\u044f. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043c\u044b \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0438 \u0448\u0430\u0431\u043b\u043e\u043d \u043f\u0438\u0441\u044c\u043c\u0430 \u0442\u0430\u043a, \u0447\u0442\u043e string.Format() \u0432\u044b\u0434\u0430\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u0443 FormatException. \u0410 \u0432 \u0442\u0435\u0441\u0442\u0435 \u0432\u0441\u0451 \u0445\u043e\u0440\u043e\u0448\u043e, \u0442\u0435\u0441\u0442 \u043e\u0442\u043b\u0438\u0447\u043d\u043e \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442. \u0418 \u0437\u0430 \u0447\u0442\u043e \u043e\u043d \u043f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442? \u041d\u0438 \u0437\u0430 \u0447\u0442\u043e. \u0422\u0430\u043a \u0447\u0442\u043e \u0444\u0430\u0439\u043b \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u043d\u0430\u0434\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439. \u041e\u0441\u0442\u0430\u0432\u0438\u043c \u044d\u0442\u043e \u043d\u0430 \u043f\u043e\u0442\u043e\u043c. <\/p>\n<p>  \u041f\u043e \u043f\u043e\u0432\u043e\u0434\u0443, IMapper \u2013 \u0432 \u044d\u0442\u043e\u043c \u043d\u0435\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438, \u043c\u044b \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u0441\u043f\u043e\u043a\u043e\u0439\u043d\u043e \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438 CommonMapper.<br \/>  \u041d\u043e \u0434\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0440\u043e\u0438\u043d\u0438\u0446\u0438\u0430\u0437\u0438\u0440\u0443\u0435\u043c IKernel \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0432 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435. \u0412 App_Start\/NinjectWebCommon.cs \u043c\u044b \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 RegisterServices \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c, \u043a\u0430\u043a \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u044b \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u044b, \u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u044d\u0442\u043e \u0432 bootstrapper.Initialize(CreateKernel). \u0412 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u043c\u044b \u043e\u0431\u0440\u0430\u0449\u0430\u0435\u043c\u0441\u044f \u043f\u043e \u043f\u043e\u0432\u043e\u0434\u0443 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0447\u0435\u0440\u0435\u0437 DependencyResolver.GetService(). \u0422\u0430\u043a \u0447\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c NinjectDependencyResolver (\/Tools\/NinjectDependencyResolver.cs):  <\/p>\n<pre><code class=\"cs\">public class NinjectDependencyResolver : IDependencyResolver     {         private readonly IKernel _kernel;          public NinjectDependencyResolver(IKernel kernel)         {             _kernel = kernel;         }          public object GetService(Type serviceType)         {             return _kernel.TryGet(serviceType);         }          public IEnumerable&lt;object&gt; GetServices(Type serviceType)         {             try             {                 return _kernel.GetAll(serviceType);             }             catch (Exception)             {                 return new List&lt;object&gt;();             }         }     } <\/code><\/pre>\n<p>  \u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0432 SetUp \u043c\u0435\u0442\u043e\u0434 (\/Setup\/UnitTestSetupFixture.cs):  <\/p>\n<pre><code class=\"cs\">[SetUp]         public virtual void Setup()         {  \t\tInitKernel(); } protected virtual IKernel InitKernel()          {             var kernel = new StandardKernel();             DependencyResolver.SetResolver(new NinjectDependencyResolver(kernel));      InitRepository(kernel); \/\/\u043f\u043e\u0442\u043e\u043c \u0441\u0434\u0435\u043b\u0430\u0435\u043c             return kernel;         }  <\/code><\/pre>\n<p>  \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c MockRepository<br \/>  (\/Mock\/Repository\/MockRepository.cs):  <\/p>\n<pre><code class=\"cs\">public partial class MockRepository : Mock&lt;IRepository&gt;     {         public MockRepository(MockBehavior mockBehavior = MockBehavior.Strict)             : base(mockBehavior)         {             GenerateRoles();             GenerateLanguages();             GenerateUsers();                      }     } <\/code><\/pre>\n<p>  (\/Mock\/Repository\/Entity\/Language.cs)  <\/p>\n<pre><code class=\"cs\">namespace LessonProject.UnitTest.Mock {     public partial class MockRepository     {         public List&lt;Language&gt; Languages { get; set; }           public void GenerateLanguages()         {             Languages = new List&lt;Language&gt;();             Languages.Add(new Language()             {                 ID = 1,                 Code = &quot;en&quot;,                 Name = &quot;English&quot;             });             Languages.Add(new Language()             {                 ID = 2,                 Code = &quot;ru&quot;,                 Name = &quot;\u0420\u0443\u0441\u0441\u043a\u0438\u0439&quot;             });             this.Setup(p =&gt; p.Languages).Returns(Languages.AsQueryable());         }     } } <\/code><\/pre>\n<p>  (\/Mock\/Repository\/Entity\/Role.cs)  <\/p>\n<pre><code class=\"cs\">    public partial class MockRepository     {         public List&lt;Role&gt; Roles { get; set; }          public void GenerateRoles()         {             Roles = new List&lt;Role&gt;();             Roles.Add(new Role()             {                 ID = 1,                 Code = &quot;admin&quot;,                 Name = &quot;Administrator&quot;             });              this.Setup(p =&gt; p.Roles).Returns(Roles.AsQueryable());         }     } <\/code><\/pre>\n<p>  (\/Mock\/Repository\/Entity\/User.cs)<\/p>\n<pre><code class=\"cs\">public partial class MockRepository     {         public List&lt;User&gt; Users { get; set; }          public void GenerateUsers()         {             Users = new List&lt;User&gt;();              var admin = new User()             {                 ID = 1,                 ActivatedDate = DateTime.Now,                 ActivatedLink = &quot;&quot;,                 Email = &quot;admin&quot;,                 FirstName = &quot;&quot;,                 LastName = &quot;&quot;,                 Password = &quot;password&quot;,                 LastVisitDate = DateTime.Now,             };              var role = Roles.First(p =&gt; p.Code == &quot;admin&quot;);             var userRole = new UserRole()             {                 User = admin,                 UserID = admin.ID,                 Role = role,                 RoleID = role.ID             };              admin.UserRoles =                  new EntitySet&lt;UserRole&gt;() {                     userRole                 };             Users.Add(admin);              Users.Add(new User()             {                 ID = 2,                 ActivatedDate = DateTime.Now,                 ActivatedLink = &quot;&quot;,                 Email = &quot;chernikov@gmail.com&quot;,                 FirstName = &quot;Andrey&quot;,                 LastName = &quot;Chernikov&quot;,                 Password = &quot;password2&quot;,                 LastVisitDate = DateTime.Now             });              this.Setup(p =&gt; p.Users).Returns(Users.AsQueryable());             this.Setup(p =&gt; p.GetUser(It.IsAny&lt;string&gt;())).Returns((string email) =&gt;                  Users.FirstOrDefault(p =&gt; string.Compare(p.Email, email, 0) == 0));      this.Setup(p =&gt; p.Login(It.IsAny&lt;string&gt;(), It.IsAny&lt;string&gt;())).Returns((string email, string password) =&gt;                 Users.FirstOrDefault(p =&gt; string.Compare(p.Email, email, 0) == 0));         }     } <\/code><\/pre>\n<p>  \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 Mock. \u0423 \u043d\u0435\u0433\u043e \u0435\u0441\u0442\u044c \u0442\u0430\u043a\u043e\u0439 \u0445\u043e\u0440\u043e\u0448\u0438\u0439 \u043c\u0435\u0442\u043e\u0434, \u043a\u0430\u043a Setup (\u043e\u043f\u044f\u0442\u044c?! \u0441\u043f\u043b\u043e\u0448\u043d\u043e\u0439 \u0441\u0435\u0442\u0430\u043f!), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<br \/>  <code>this.Setup(\u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u044e\u0442).Returns(\u0447\u0442\u043e \u043c\u044b \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u043c \u043d\u0430 \u044d\u0442\u043e);<\/code><\/p>\n<p>  \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:<br \/>  <code>this.Setup(p =&gt; p.WillYou()).Returns(true);<\/code><\/p>\n<p>  \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435, \u043a\u0430\u043a\u0438\u0435 \u0435\u0449\u0435 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b:  <\/p>\n<ul>\n<li>\u041c\u0435\u0442\u043e\u0434\u044b<br \/> \n<pre><code class=\"cs\">var mock = new Mock&lt;IFoo&gt;(); mock.Setup(foo =&gt; foo.DoSomething(&quot;ping&quot;)).Returns(true); <\/code><\/pre>\n<ul>\n<li>\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 out <br \/> \n<pre><code class=\"cs\">var outString = &quot;ack&quot;; mock.Setup(foo =&gt; foo.TryParse(&quot;ping&quot;, out outString)).Returns(true); <\/code><\/pre>\n<p>  <\/li>\n<li>\u0441\u0441\u044b\u043b\u043e\u0447\u043d\u044b\u0439 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440<br \/> \n<pre><code class=\"cs\">var instance = new Bar(); mock.Setup(foo =&gt; foo.Submit(ref instance)).Returns(true); <\/code><\/pre>\n<p>  <\/li>\n<li>\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c \u043e\u0442 \u0432\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f (\u043c\u043e\u0436\u043d\u043e \u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432)<br \/> \n<pre><code class=\"cs\">mock.Setup(x =&gt; x.DoSomething(It.IsAny&lt;string&gt;()))                 .Returns((string s) =&gt; s.ToLower()); <\/code><\/pre>\n<p>  <\/li>\n<li>\u043a\u0438\u0434\u0430\u0435\u043c \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<br \/> \n<pre><code class=\"cs\">mock.Setup(foo =&gt; foo.DoSomething(&quot;reset&quot;)).Throws&lt;InvalidOperationException&gt;(); mock.Setup(foo =&gt; foo.DoSomething(&quot;&quot;)).Throws(new ArgumentException(&quot;command&quot;); <\/code><\/pre>\n<p>  <\/li>\n<li>\u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0434\u043b\u044f (???) \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 Callback<br \/> \n<pre><code class=\"cs\">var mock = new Mock&lt;IFoo&gt;(); var calls = 0; mock.Setup(foo =&gt; foo.GetCountThing())     .Returns(() =&gt; calls)     .Callback(() =&gt; calls++); <\/code><\/pre>\n<p>  <\/li>\n<\/ul>\n<p>  <\/li>\n<li>\u0421\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0432\u0438\u0435 \u043d\u0430 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b<br \/> \n<ul>\n<li>\u043b\u044e\u0431\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435<br \/> \n<pre><code class=\"cs\">mock.Setup(foo =&gt; foo.DoSomething(It.IsAny&lt;string&gt;())).Returns(true); <\/code><\/pre>\n<p>  <\/li>\n<li>\u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u0447\u0435\u0440\u0435\u0437 Func&lt;bool, T&gt;<br \/> \n<pre><code class=\"cs\">mock.Setup(foo =&gt; foo.Add(It.Is&lt;int&gt;(i =&gt; i % 2 == 0))).Returns(true); <\/code><\/pre>\n<p>  <\/li>\n<li>\u043d\u0430\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u0435 \u0432 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0435<br \/> \n<pre><code class=\"cs\">mock.Setup(foo =&gt; foo.Add(It.IsInRange&lt;int&gt;(0, 10, Range.Inclusive))).Returns(true); <\/code><\/pre>\n<p>  <\/li>\n<li>Regex \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435<br \/> \n<pre><code class=\"cs\">mock.Setup(x =&gt; x.DoSomething(It.IsRegex(&quot;[a-d]+&quot;, RegexOptions.IgnoreCase))).Returns(&quot;foo&quot;); <\/code><\/pre>\n<p>  <\/li>\n<\/ul>\n<p>  <\/li>\n<li>\u0421\u0432\u043e\u0439\u0441\u0442\u0432\u0430<br \/> \n<ul>\n<li>\u041b\u044e\u0431\u043e\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e<br \/> \n<pre><code class=\"cs\">mock.Setup(foo =&gt; foo.Name).Returns(&quot;bar&quot;); <\/code><\/pre>\n<p>  <\/li>\n<li>\u041b\u044e\u0431\u043e\u0439 \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u0438 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e<br \/> \n<pre><code class=\"cs\">mock.Setup(foo =&gt; foo.Bar.Baz.Name).Returns(&quot;baz&quot;); <\/code><\/pre>\n<p>  <\/li>\n<\/ul>\n<p>  <\/li>\n<li>\u041e\u0431\u0440\u0430\u0442\u043d\u044b\u0435 \u0432\u044b\u0437\u043e\u0432\u044b (callback)<br \/> \n<ul>\n<li>\u0411\u0435\u0437 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432<br \/> \n<pre><code class=\"cs\">mock.Setup(foo =&gt; foo.Execute(&quot;ping&quot;))                 .Returns(true)                 .Callback(() =&gt; calls++); <\/code><\/pre>\n<p>  <\/li>\n<li>\u0421 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u043c <br \/> \n<pre><code class=\"cs\">     mock.Setup(foo =&gt; foo.Execute(It.IsAny&lt;string&gt;()))                 .Returns(true)                 .Callback((string s) =&gt; calls.Add(s)); <\/code><\/pre>\n<p>  <\/li>\n<li>\u0421 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u043c, \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441<br \/> \n<pre><code class=\"cs\">            mock.Setup(foo =&gt; foo.Execute(It.IsAny&lt;string&gt;()))                 .Returns(true)                 .Callback&lt;string&gt;(s =&gt; calls.Add(s)); <\/code><\/pre>\n<p>  \u041d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432   <\/p>\n<pre><code class=\"cs\">     mock.Setup(foo =&gt; foo.Execute(It.IsAny&lt;int&gt;(), It.IsAny&lt;string&gt;()))                 .Returns(true)                 .Callback&lt;int, string&gt;((i, s) =&gt; calls.Add(s)); <\/code><\/pre>\n<p>  \u0414\u043e \u0438 \u043f\u043e\u0441\u043b\u0435 \u0432\u044b\u0437\u043e\u0432\u0430  <\/p>\n<pre><code class=\"cs\">            mock.Setup(foo =&gt; foo.Execute(&quot;ping&quot;))                 .Callback(() =&gt; Console.WriteLine(&quot;Before returns&quot;))                 .Returns(true)                 .Callback(() =&gt; Console.WriteLine(&quot;After returns&quot;)); <\/code><\/pre>\n<\/li>\n<\/ul>\n<p>  \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 (Mock \u043e\u0431\u044a\u0435\u043a\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0439 \u043a \u0441\u0432\u043e\u0438\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c, \u0442\u0435\u043c \u0441\u0430\u043c\u044b\u043c \u043c\u044b \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043b\u0438 \u0431\u044b\u043b \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d \u043a\u043e\u0434)  <\/p>\n<ul>\n<li>\u041e\u0431\u044b\u0447\u043d\u0430\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430, \u0447\u0442\u043e \u0431\u044b\u043b \u0432\u044b\u0437\u0432\u0430\u043d \u043c\u0435\u0442\u043e\u0434 Execute \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u043c \u201cping\u201d<br \/> \n<pre><code class=\"cs\">mock.Verify(foo =&gt; foo.Execute(&quot;ping&quot;)); <\/code><\/pre>\n<p>  <\/li>\n<li> \u0421 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0435<br \/> \n<pre><code class=\"cs\">     mock.Verify(foo =&gt; foo.Execute(&quot;ping&quot;), &quot;When doing operation X, the service should be pinged always&quot;); <\/code><\/pre>\n<p>  <\/li>\n<li> \u041d\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u043b \u0431\u044b\u0442\u044c \u0432\u044b\u0437\u0432\u0430\u043d \u043d\u0438 \u0440\u0430\u0437\u0443<br \/> \n<pre><code class=\"cs\">mock.Verify(foo =&gt; foo.Execute(&quot;ping&quot;), Times.Never()); <\/code><\/pre>\n<p>  <\/li>\n<li> \u0425\u043e\u0442\u044f \u0431\u044b \u0440\u0430\u0437 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u043b \u0431\u044b\u0442\u044c \u0432\u044b\u0437\u0432\u0430\u043d<br \/> \n<pre><code class=\"cs\">mock.Verify(foo =&gt; foo.Execute(&quot;ping&quot;), Times.AtLeastOnce()); mock.VerifyGet(foo =&gt; foo.Name); <\/code><\/pre>\n<\/li>\n<li> \u0414\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u043b \u0431\u044b\u0442\u044c \u0432\u044b\u0437\u0432\u0430\u043d \u0438\u043c\u0435\u043d\u043d\u043e \u0441\u0435\u0442\u0442\u0435\u0440 \u0434\u043b\u044f \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430<br \/> \n<pre><code class=\"cs\">            mock.VerifySet(foo =&gt; foo.Name); <\/code><\/pre>\n<p>  <\/li>\n<li> \u0414\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u043b \u0431\u044b\u0442\u044c \u0432\u044b\u0437\u0432\u0430\u043d \u0441\u0435\u0442\u0442\u0435\u0440 \u0441\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u201cfoo\u201d<br \/> \n<pre><code class=\"cs\">      mock.VerifySet(foo =&gt; foo.Name = &quot;foo&quot;); <\/code><\/pre>\n<p>  <\/li>\n<li> \u0421\u0435\u0442\u0442\u0435\u0440 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u043b \u0431\u044b\u0442\u044c \u0432\u044b\u0437\u0432\u0430\u043d \u0441\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u0432 \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u043c \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0435<br \/> \n<pre><code class=\"cs\">mock.VerifySet(foo =&gt; foo.Value = It.IsInRange(1, 5, Range.Inclusive)); <\/code><\/pre>\n<p>  <\/li>\n<\/ul>\n<p>  \u0425\u043e\u0440\u043e\u0448\u043e, \u044d\u0442\u043e\u0433\u043e \u043d\u0430\u043c \u043f\u043e\u043a\u0430 \u0445\u0432\u0430\u0442\u0438\u0442, \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0435 \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0437\u0434\u0435\u0441\u044c:<br \/>  <a href=\"https:\/\/code.google.com\/p\/moq\/wiki\/QuickStart\">https:\/\/code.google.com\/p\/moq\/wiki\/QuickStart <\/a><\/p>\n<p>  \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u0441\u044f \u043e\u0431\u0440\u0430\u0442\u043d\u043e \u0432 UnitTestSetupFixture.cs (\/Setup\/UnitTestSetupFixture.cs) \u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u043d\u0444\u0438\u0433:  <\/p>\n<pre><code class=\"cs\">protected virtual void InitRepository(StandardKernel kernel)         {             kernel.Bind&lt;MockRepository&gt;().To&lt;MockRepository&gt;().InThreadScope();             kernel.Bind&lt;IRepository&gt;().ToMethod(p =&gt; kernel.Get&lt;MockRepository&gt;().Object);         } <\/code><\/pre>\n<p>  \u041f\u0440\u043e\u0432\u0435\u0440\u0438\u043c \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043d\u0430\u0448 \u0432\u044b\u0432\u043e\u0434, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u043a\u043b\u0430\u0441\u0441 \/Default\/Controllers\/UserController:cs:  <\/p>\n<pre><code class=\"cs\">[Test]         public void Index_GetPageableDataOfUsers_CountOfUsersIsTwo()         {             \/\/init             var controller = DependencyResolver.Current.GetService&lt;Areas.Default.Controllers.UserController&gt;();             \/\/act             var result = controller.Index();              Assert.IsInstanceOf&lt;ViewResult&gt;(result);             Assert.IsInstanceOf&lt;PageableData&lt;User&gt;&gt;(((ViewResult)result).Model);             var count = ((PageableData&lt;User&gt;)((ViewResult)result).Model).List.Count();              Assert.AreEqual(2, count);         } <\/code><\/pre>\n<p>  \u0412 BaseController.cs (\/LessonProject\/Controllers\/BaseController.cs) \u0443\u0431\u0435\u0440\u0435\u043c \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b <code>Inject <\/code> \u0443 \u0441\u0432\u043e\u0439\u0441\u0442\u0432 <code>Auth<\/code> \u0438 <code>Config<\/code> (\u0438\u043d\u0430\u0447\u0435 \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u043d\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430 \u043d\u0435 \u0441\u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u043e\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u0438 \u0432\u0435\u0440\u043d\u0435\u0442 null). \u041a\u0441\u0442\u0430\u0442\u0438 \u043e \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0435. \u041c\u044b \u0434\u0435\u043b\u0430\u0435\u043c \u0438\u043c\u0435\u043d\u043d\u043e \u0442\u0430\u043a\u0443\u044e \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e, \u0447\u0442\u043e\u0431\u044b \u0432\u0441\u0435 Inject-\u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0431\u044b\u043b\u0438 \u043f\u0440\u043e\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u044b. \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c, \u0438, \u043f\u0440\u0430\u0432\u0434\u0430, count == 2. \u041e\u0442\u043b\u0438\u0447\u043d\u043e, MockRepository \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442. \u0412\u0435\u0440\u043d\u0435\u043c \u043d\u0430\u0437\u0430\u0434 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b <code>Inject<\/code>.<br \/>  \u041a\u0441\u0442\u0430\u0442\u0438, \u0442\u0435\u0441\u0442\u044b \u043d\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0442\u0441\u044f \u043e\u0431\u044b\u0447\u043d\u043e \u0432 \u0434\u0435\u0431\u0430\u0433-\u0440\u0435\u0436\u0438\u043c\u0435, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c Debug \u043d\u0430\u0434\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a:<br \/>  \u0422\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u0441 Config. \u042d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u043a\u0440\u0443\u0442\u043e!<\/p>\n<h5>TestConfig<\/h5>\n<p>  \u0427\u0442\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c. \u041d\u0430\u043c \u043d\u0443\u0436\u043d\u043e:  <\/p>\n<ul>\n<li>\u0412\u0437\u044f\u0442\u044c Web.Config c \u043f\u0440\u043e\u0435\u043a\u0442\u0430 LessonProject (\u043a\u0430\u043a\u0438\u043c-\u0442\u043e \u0445\u0438\u0442\u0440\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c)<\/li>\n<li>\u0418 \u043d\u0430 \u0435\u0433\u043e \u0431\u0430\u0437\u0435 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u0435\u043a\u0438\u0439 \u043a\u043b\u0430\u0441\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c IConfig \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441<\/li>\n<li>\u041d\u0443 \u0438 \u043f\u043e\u0446\u0435\u043f\u0438\u0442\u044c \u043d\u0430 Ninject Kernel<\/li>\n<li>\u0418 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c.<\/li>\n<\/ul>\n<p>  \u041d\u0430\u0447\u043d\u0435\u043c. \u0414\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u0432\u0437\u044f\u0442\u044c Web.Config \u2013 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0432 \u0441\u0432\u043e\u044e \u043f\u0430\u043f\u043a\u0443. \u041d\u0430\u0437\u043e\u0432\u0435\u043c \u0435\u0451 Sandbox. \u0422\u0435\u043f\u0435\u0440\u044c \u0441\u043a\u043e\u043f\u0438\u0440\u0443\u0435\u043c, \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u043c \u043d\u0430 pre-build Event \u0432 Project Properties:<br \/>  <img decoding=\"async\" src=\"http:\/\/habrastorage.org\/storage2\/607\/fce\/2d1\/607fce2d13b279516dfd0be33240f601.jpg\"\/><\/p>\n<pre><code class=\"bash\">xcopy $(SolutionDir)LessonProject\\Web.config $(ProjectDir)Sandbox\\ \/y <\/code><\/pre>\n<p>  \u041f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u0431\u0438\u043b\u0434\u0430 \u043c\u044b \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u043c Web.config (\u0438, \u0435\u0441\u043b\u0438 \u043d\u0430\u0434\u043e, \u0442\u043e \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c) \u043a \u0441\u0435\u0431\u0435 \u0432 Sandbox.<br \/>  \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c TestConfig.cs \u0438 \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u0431\u0443\u0434\u0435\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u0430\u0448 \u0444\u0430\u0439\u043b (\/Tools\/TestConfig.cs):  <\/p>\n<pre><code class=\"cs\">public class TestConfig : IConfig     {         private Configuration configuration;          public TestConfig(string configPath)         {             var configFileMap = new ExeConfigurationFileMap();             configFileMap.ExeConfigFilename = configPath;             configuration = ConfigurationManager.OpenMappedExeConfiguration(configFileMap, ConfigurationUserLevel.None);         }           public string ConnectionStrings(string connectionString)         {             return configuration.ConnectionStrings.ConnectionStrings[connectionString].ConnectionString;         }          public string Lang         {             get             {                 return configuration.AppSettings.Settings[&quot;Lang&quot;].Value;             }         }          public bool EnableMail         {             get             {                 return bool.Parse(configuration.AppSettings.Settings[&quot;EnableMail&quot;].Value);             }         }          public IQueryable&lt;IconSize&gt; IconSizes         {             get             {                 IconSizesConfigSection configInfo = (IconSizesConfigSection)configuration.GetSection(&quot;iconConfig&quot;);                 if (configInfo != null)                 {                     return configInfo.IconSizes.OfType&lt;IconSize&gt;().AsQueryable&lt;IconSize&gt;();                 }                 return null;             }         }          public IQueryable&lt;MimeType&gt; MimeTypes         {             get             {                 MimeTypesConfigSection configInfo = (MimeTypesConfigSection)configuration.GetSection(&quot;mimeConfig&quot;);                 return configInfo.MimeTypes.OfType&lt;MimeType&gt;().AsQueryable&lt;MimeType&gt;();             }         }          public IQueryable&lt;MailTemplate&gt; MailTemplates         {             get {                 MailTemplateConfigSection configInfo = (MailTemplateConfigSection)configuration.GetSection(&quot;mailTemplatesConfig&quot;);                 return configInfo.MailTemplates.OfType&lt;MailTemplate&gt;().AsQueryable&lt;MailTemplate&gt;();              }         }          public MailSetting MailSetting         {             get             {                 return (MailSetting)configuration.GetSection(&quot;mailConfig&quot;);             }         }          public SmsSetting SmsSetting         {             get              {                 return (SmsSetting)configuration.GetSection(&quot;smsConfig&quot;);             }         }     } <\/code><\/pre>\n<p>  \u0418 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0432 UnitTestSetupFixture.cs (\/Setup\/UnitTestSetupFixture.cs):   <\/p>\n<pre><code class=\"cs\"> protected virtual void InitConfig(StandardKernel kernel)         {             var fullPath = new FileInfo(Sandbox + &quot;\/Web.config&quot;).FullName;             kernel.Bind&lt;IConfig&gt;().ToMethod(c =&gt; new TestConfig(fullPath));         } <\/code><\/pre>\n<p>  \u2003<br \/>  \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0442\u0435\u0441\u0442 \u043d\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0435:  <\/p>\n<pre><code class=\"cs\">[TestFixture]     public class MailTemplateTest     {         [Test]         public void MailTemplates_ExistRegisterTemplate_Exist()         {             var config = DependencyResolver.Current.GetService&lt;IConfig&gt;();             var template = config.MailTemplates.FirstOrDefault(p =&gt; p.Name.StartsWith(&quot;Register&quot;));             Assert.IsNotNull(template);         }     } <\/code><\/pre>\n<p>  \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0432\u0443\u0430\u043b\u044f! \u041f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043a \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 IAuthentication. <\/p>\n<h5>Authentication<\/h5>\n<p>  \u0412 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438, \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u0443\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u043a\u043e\u0434 \u0432 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0435, \u043c\u044b \u0443\u0436\u0435 \u0438\u043c\u0435\u0435\u043c \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442, \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435, \u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 http-\u0437\u0430\u043f\u0440\u043e\u0441\u043e\u043c. \u0422.\u0435. \u044d\u0442\u043e \u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b, \u0438 \u043a\u0443\u043a\u0438\u0441\u044b, \u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u043e \u0432\u0435\u0440\u0441\u0438\u0438 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430, \u0438 \u043a\u0430\u043a\u043e\u0432\u043e \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u044d\u043a\u0440\u0430\u043d\u0430, \u0438 \u043a\u0430\u043a\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430. \u0412 \u043e\u0431\u0449\u0435\u043c, \u044d\u0442\u043e \u0432\u0441\u0451 \u2013 HttpContext. \u0421\u043b\u0435\u0434\u0443\u0435\u0442 \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c, \u0447\u0442\u043e \u043c\u044b \u043f\u0440\u0438 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u043e\u043c\u0435\u0449\u0430\u0435\u043c \u0432 \u043a\u0443\u043a\u0438\u0441\u044b \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u0434\u0430\u043d\u043d\u044b\u0435, \u0430 \u043f\u043e\u0442\u043e\u043c \u0434\u043e\u0441\u0442\u0430\u0435\u043c \u0438\u0445 \u0438 \u0432\u0441\u0451. \u0421\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 IAuthCookieProvider, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0442\u0438\u043f\u0430 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u043a\u0443\u043a\u0438\u0441\u044b<br \/>  IAuthCookieProvider.cs (LessonProject\/Global\/Auth\/IAuthCookieProvider):  <\/p>\n<pre><code class=\"cs\">public interface IAuthCookieProvider     {         HttpCookie GetCookie(string cookieName);          void SetCookie(HttpCookie cookie);     } <\/code><\/pre>\n<p>  \u0418 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0435\u0433\u043e \u0434\u043b\u044f HttpAuthCookieProvider.cs (\/Global\/Auth\/HttpAuthCookieProvider.cs):  <\/p>\n<pre><code class=\"cs\">public class HttpContextCookieProvider : IAuthCookieProvider     {         public HttpContextCookieProvider(HttpContext HttpContext)         {             this.HttpContext = HttpContext;         }          protected HttpContext HttpContext { get; set; }          public HttpCookie GetCookie(string cookieName)         {             return HttpContext.Request.Cookies.Get(cookieName);         }          public void SetCookie(HttpCookie cookie)         {             HttpContext.Response.Cookies.Set(cookie);         }     } <\/code><\/pre>\n<p>  \u0418 \u0442\u0435\u043f\u0435\u0440\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u044d\u0442\u0443 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 Cookies \u0432 CustomAuthentication (\/Global\/Auth\/CustomAuthentication.cs):  <\/p>\n<pre><code class=\"cs\">public IAuthCookieProvider AuthCookieProvider { get; set; } <\/code><\/pre>\n<p>  \u0438 \u0432\u043c\u0435\u0441\u0442\u043e HttpContext.Request.Cookies.Get \u2013 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c GetCookie() \u0438 <br \/>  HttpContext.Response.Cookies.Set \u2013 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e SetCookie().<br \/>  \u0418\u0437\u043c\u0435\u043d\u044f\u0435\u043c \u0438 \u0432 IAuthencation.cs (\/Global\/Auth\/IAuthencation.cs):   <\/p>\n<pre><code class=\"cs\"> public interface IAuthentication     {         \/\/\/ &lt;summary&gt;         \/\/\/ \u041a\u043e\u043d\u0435\u043a\u0441\u0442 (\u0442\u0443\u0442 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0437\u0430\u043f\u0440\u043e\u0441\u0443 \u0438 \u043a\u0443\u043a\u0438\u0441\u0430\u043c)         \/\/\/ &lt;\/summary&gt;         IAuthCookieProvider AuthCookieProvider { get; set; }  <\/code><\/pre>\n<p>  \u0418 \u0432 AuthHttpModule.cs (\/Global\/Auth\/AuthHttpModule.cs):  <\/p>\n<pre><code class=\"cs\">var auth = DependencyResolver.Current.GetService&lt;IAuthentication&gt;();       auth.AuthCookieProvider = new HttpContextCookieProvider(context); <\/code><\/pre>\n<h5>MockHttpContext <\/h5>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c Mock-\u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0434\u043b\u044f HttpContext \u0432 LessonProject.UnitTest:<\/p>\n<pre><code class=\"cs\">MockHttpContext.cs \u0432 (\/Mock\/HttpContext.cs): public class MockHttpContext : Mock&lt;HttpContextBase&gt;     {         [Inject]         public HttpCookieCollection Cookies { get; set; }          public MockHttpCachePolicy Cache { get; set; }          public MockHttpBrowserCapabilities Browser { get; set; }          public MockHttpSessionState SessionState { get; set; }          public MockHttpServerUtility ServerUtility { get; set; }          public MockHttpResponse Response { get; set; }          public MockHttpRequest Request { get; set; }          public MockHttpContext(MockBehavior mockBehavior = MockBehavior.Strict)             : this(null, mockBehavior)         {         }          public MockHttpContext(IAuthentication auth, MockBehavior mockBehavior = MockBehavior.Strict)             : base(mockBehavior)         {             \/\/request              Browser = new MockHttpBrowserCapabilities(mockBehavior);             Browser.Setup(b =&gt; b.IsMobileDevice).Returns(false);              Request = new MockHttpRequest(mockBehavior);             Request.Setup(r =&gt; r.Cookies).Returns(Cookies);             Request.Setup(r =&gt; r.ValidateInput());             Request.Setup(r =&gt; r.UserAgent).Returns(&quot;Mozilla\/5.0 (Windows NT 6.1; WOW64) AppleWebKit\/537.11 (KHTML, like Gecko) Chrome\/23.0.1271.64 Safari\/537.11&quot;);             Request.Setup(r =&gt; r.Browser).Returns(Browser.Object);             this.Setup(p =&gt; p.Request).Returns(Request.Object);              \/\/response             Cache = new MockHttpCachePolicy(MockBehavior.Loose);                         Response = new MockHttpResponse(mockBehavior);             Response.Setup(r =&gt; r.Cookies).Returns(Cookies);             Response.Setup(r =&gt; r.Cache).Returns(Cache.Object);             this.Setup(p =&gt; p.Response).Returns(Response.Object);              \/\/user             if (auth != null)             {                 this.Setup(p =&gt; p.User).Returns(() =&gt; auth.CurrentUser);             }             else             {                 this.Setup(p =&gt; p.User).Returns(new UserProvider(&quot;&quot;, null));             }              \/\/Session State             SessionState = new MockHttpSessionState();             this.Setup(p =&gt; p.Session).Returns(SessionState.Object);              \/\/Server Utility             ServerUtility = new MockHttpServerUtility(mockBehavior);             this.Setup(p =&gt; p.Server).Returns(ServerUtility.Object);              \/\/Items             var items = new ListDictionary();             this.Setup(p =&gt; p.Items).Returns(items);         }     } <\/code><\/pre>\n<p>  \u041a\u0440\u043e\u043c\u0435 \u044d\u0442\u043e\u0433\u043e \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0435\u0449\u0435 \u0442\u0430\u043a\u0438\u0435 \u043a\u043b\u0430\u0441\u0441\u044b:  <\/p>\n<ul>\n<li>MockHttpCachePolicy<\/li>\n<li>MockHttpBrowserCapabilities <\/li>\n<li>MockHttpSessionState<\/li>\n<li>MockHttpServerUtility<\/li>\n<li>MockHttpResponse<\/li>\n<li>MockHttpRequest<\/li>\n<\/ul>\n<p>  \u0412\u0441\u0435 \u044d\u0442\u0438 mock-\u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0432\u0435\u0441\u044c\u043c\u0430 \u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u044b, \u043a\u0440\u043e\u043c\u0435 MockSessionState, \u0433\u0434\u0435 \u0438 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f session-storage (\/Mock\/Http\/MockHttpSessionState.cs):  <\/p>\n<pre><code class=\"cs\">public class MockHttpSessionState : Mock&lt;HttpSessionStateBase&gt;     {         Dictionary&lt;string, object&gt; sessionStorage;           public MockHttpSessionState(MockBehavior mockBehavior = MockBehavior.Strict)             : base(mockBehavior)         {             sessionStorage = new Dictionary&lt;string, object&gt;();             this.Setup(p =&gt; p[It.IsAny&lt;string&gt;()]).Returns((string index) =&gt; sessionStorage[index]);             this.Setup(p =&gt; p.Add(It.IsAny&lt;string&gt;(), It.IsAny&lt;object&gt;())).Callback&lt;string, object&gt;((name, obj) =&gt;             {                 if (!sessionStorage.ContainsKey(name))                 {                     sessionStorage.Add(name, obj);                 }                 else                 {                     sessionStorage[name] = obj;                 }             });         }     } <\/code><\/pre>\n<p>  \u0421\u043e\u0437\u0434\u0430\u0435\u043c FakeAuthCookieProvider.cs (\/Fake\/FakeAuthCookieProvider.cs):  <\/p>\n<pre><code class=\"cs\"> public class FakeAuthCookieProvider : IAuthCookieProvider     {         [Inject]         public HttpCookieCollection Cookies { get; set; }          public HttpCookie GetCookie(string cookieName)         {             return Cookies.Get(cookieName);         }          public void SetCookie(HttpCookie cookie)         {             if (Cookies.Get(cookie.Name) != null)             {                 Cookies.Remove(cookie.Name);             }             Cookies.Add(cookie);         }     } <\/code><\/pre>\n<p>  \u0424\u0443\u0445! \u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u044d\u0442\u043e \u0432 UnitTestSetupFixture.cs (\/Setup\/UnitTestSetupFixture.cs):  <\/p>\n<pre><code class=\"cs\">protected virtual void InitAuth(StandardKernel kernel)         {             kernel.Bind&lt;HttpCookieCollection&gt;().To&lt;HttpCookieCollection&gt;();             kernel.Bind&lt;IAuthCookieProvider&gt;().To&lt;FakeAuthCookieProvider&gt;().InSingletonScope();             kernel.Bind&lt;IAuthentication&gt;().ToMethod&lt;CustomAuthentication&gt;(c =&gt;             {                 var auth = new CustomAuthentication();                 auth.AuthCookieProvider = kernel.Get&lt;IAuthCookieProvider&gt;();                 return auth;             });         } <\/code><\/pre>\n<p>  \u0417\u0430\u043c\u0435\u0442\u0438\u043c, \u0447\u0442\u043e Bind \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043d\u0430 SingletonScope(), \u0442.\u0435. \u0435\u0434\u0438\u043d\u043e\u0436\u0434\u044b \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u0432\u0448\u0438\u0441\u044c \u0432 \u043a\u0430\u043a\u043e\u043c-\u0442\u043e \u0442\u0435\u0441\u0442\u0435, \u043c\u044b \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u0442\u0435\u0441\u0442\u0430\u0445 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u0443 \u0436\u0435 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044e.<\/p>\n<p>  \u041a\u043e\u043c\u043f\u0438\u043b\u0438\u043c \u0438 \u043f\u044b\u0442\u0430\u0435\u043c\u0441\u044f \u0441 \u044d\u0442\u0438\u043c \u0432\u0441\u0435\u043c \u0432\u0437\u043b\u0435\u0442\u0435\u0442\u044c. \u0421\u0435\u0439\u0447\u0430\u0441 \u043d\u0430\u0447\u043d\u0435\u0442\u0441\u044f \u043c\u0430\u0433\u0438\u044f\u2026<\/p>\n<h5>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438<\/h5>\n<p>  \u0415\u0441\u043b\u0438 \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u044b\u0437\u043e\u0432\u0435\u043c \u0447\u0442\u043e-\u0442\u043e \u0442\u0438\u043f\u0430:  <\/p>\n<pre><code class=\"cs\">var registerUser = new UserView()             {                 Email = &quot;user@sample.com&quot;,                 Password = &quot;123456&quot;,                 ConfirmPassword = &quot;1234567&quot;,                 AvatarPath = &quot;\/file\/no-image.jpg&quot;,                 BirthdateDay = 1,                 BirthdateMonth = 12,                 BirthdateYear = 1987,                 Captcha = &quot;1234&quot;             };             var result = controller.Register(registerUser); <\/code><\/pre>\n<p>  \u0422\u043e, \u0432\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u043d\u0438\u043a\u0430\u043a\u0430\u044f \u043d\u0435\u044f\u0432\u043d\u0430\u044f \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u0441\u044f, \u0430 \u0432\u043e-\u0432\u0442\u043e\u0440\u044b\u0445, \u0443 \u043d\u0430\u0441 \u0442\u0430\u043c \u0435\u0441\u0442\u044c session \u0438 \u043c\u044b \u0435\u0435 \u043d\u0435 \u043f\u0440\u043e\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043b\u0438, \u043e\u043d\u0430 null \u0438 \u0432\u0441\u0451 \u2013 \u043e\u0448\u0438\u0431\u043a\u0430. \u0422\u0430\u043a \u0447\u0442\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 (\u0442\u0430, \u0447\u0442\u043e \u0432 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430\u0445) \u0431\u0443\u0434\u0435\u043c \u0443\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441. \u041d\u0430\u0437\u043e\u0432\u0435\u043c \u0435\u0433\u043e \u0412\u0430\u043b\u0438\u0434\u0430\u0442\u043e\u0440 \u0412\u0430\u043b\u0438\u0434\u0430\u0442\u043e\u0440\u043e\u0432\u0438\u0447 (\/Tools\/Validator.cs):  <\/p>\n<pre><code class=\"cs\">public class ValidatorException : Exception     {         public ValidationAttribute Attribute { get; private set; }          public ValidatorException(ValidationException ex, ValidationAttribute attribute)             : base(attribute.GetType().Name, ex)         {             Attribute = attribute;         }     }      public class Validator     {         public static void ValidateObject&lt;T&gt;(T obj)         {             var type = typeof(T);             var meta = type.GetCustomAttributes(false).OfType&lt;MetadataTypeAttribute&gt;().FirstOrDefault();             if (meta != null)             {                 type = meta.MetadataClassType;             }              var typeAttributes = type.GetCustomAttributes(typeof(ValidationAttribute), true).OfType&lt;ValidationAttribute&gt;();             var validationContext = new ValidationContext(obj);             foreach (var attribute in typeAttributes)             {                 try                 {                     attribute.Validate(obj, validationContext);                 }                 catch (ValidationException ex)                 {                     throw new ValidatorException(ex, attribute);                 }             }              var propertyInfo = type.GetProperties();             foreach (var info in propertyInfo)             {                 var attributes = info.GetCustomAttributes(typeof(ValidationAttribute), true).OfType&lt;ValidationAttribute&gt;();                 foreach (var attribute in attributes)                 {                     var objPropInfo = obj.GetType().GetProperty(info.Name);                     try                     {                         attribute.Validate(objPropInfo.GetValue(obj, null), validationContext);                     }                     catch (ValidationException ex)                     {                         throw new ValidatorException(ex, attribute);                     }                 }             }         }     } <\/code><\/pre>\n<p>  \u0418\u0442\u0430\u043a, \u0447\u0442\u043e \u0442\u0443\u0442 \u0443 \u043d\u0430\u0441 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442. \u0412\u043d\u0430\u0447\u0430\u043b\u0435 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0432\u0441\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u043a\u043b\u0430\u0441\u0441\u0430 T, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0442\u043d\u043e\u0441\u044f\u0442\u0441\u044f \u043a \u0442\u0438\u043f\u0443 ValidationAttribute:   <\/p>\n<pre><code class=\"cs\">var typeAttributes = type.GetCustomAttributes(typeof(ValidationAttribute), true).OfType&lt;ValidationAttribute&gt;();             var validationContext = new ValidationContext(obj);             foreach (var attribute in typeAttributes)             {                 try                 {                     attribute.Validate(obj, validationContext);                 }                 catch (ValidationException ex)                 {                     throw new ValidatorException(ex, attribute);                 }             } <\/code><\/pre>\n<p>  \u041f\u043e\u0442\u043e\u043c \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430:  <\/p>\n<pre><code class=\"cs\">var propertyInfo = type.GetProperties();             foreach (var info in propertyInfo)             {                 var attributes = info.GetCustomAttributes(typeof(ValidationAttribute), true).OfType&lt;ValidationAttribute&gt;();                 foreach (var attribute in attributes)                 {                     var objPropInfo = obj.GetType().GetProperty(info.Name);                     try                     {                         attribute.Validate(objPropInfo.GetValue(obj, null), validationContext);                     }                     catch (ValidationException ex)                     {                         throw new ValidatorException(ex, attribute);                     }                 }             } <\/code><\/pre>\n<p>  \u0415\u0441\u043b\u0438 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f \u043d\u0435 \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442, \u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435, \u0438 \u043c\u044b \u043e\u0431\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u0435\u0433\u043e \u0432 ValidatorException, \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u044f \u0435\u0449\u0435 \u0438 \u0430\u0442\u0440\u0438\u0431\u0443\u0442, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u043e \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435.<br \/>  \u0422\u0435\u043f\u0435\u0440\u044c \u043f\u043e \u043f\u043e\u0432\u043e\u0434\u0443 \u043a\u0430\u043f\u0447\u0438 \u0438 Session. \u041c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0443 \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 (MockHttpContext):  <\/p>\n<pre><code class=\"cs\">var controller = DependencyResolver.Current.GetService&lt;Areas.Default.Controllers.UserController&gt;();             var httpContext = new MockHttpContext().Object;             ControllerContext context = new ControllerContext(new RequestContext(httpContext,  new RouteData()), controller);             controller.ControllerContext = context;             controller.Session.Add(CaptchaImage.CaptchaValueKey, &quot;1111&quot;); <\/code><\/pre>\n<p>  \u0418 \u0442\u0435\u043f\u0435\u0440\u044c \u0432\u0441\u0451 \u0432\u043c\u0435\u0441\u0442\u0435:  <\/p>\n<pre><code class=\"cs\">[Test]         public void Index_RegisterUserWithDifferentPassword_ExceptionCompare()         {             \/\/init             var controller = DependencyResolver.Current.GetService&lt;Areas.Default.Controllers.UserController&gt;();             var httpContext = new MockHttpContext().Object;             ControllerContext context = new ControllerContext(new RequestContext(httpContext,  new RouteData()), controller);             controller.ControllerContext = context;              \/\/act             var registerUserView = new UserView()             {                 Email = &quot;user@sample.com&quot;,                 Password = &quot;123456&quot;,                 ConfirmPassword = &quot;1234567&quot;,                 AvatarPath = &quot;\/file\/no-image.jpg&quot;,                 BirthdateDay = 1,                 BirthdateMonth = 12,                 BirthdateYear = 1987,                 Captcha = &quot;1111&quot;             };             try             {                 Validator.ValidateObject&lt;UserView&gt;(registerUserView);             }             catch (Exception ex)             {                 Assert.IsInstanceOf&lt;ValidatorException&gt;(ex);                 Assert.IsInstanceOf&lt;System.ComponentModel.DataAnnotations.CompareAttribute&gt;(((ValidatorException)ex).Attribute);             }         }  <\/code><\/pre>\n<p>  \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c, \u0438 \u0432\u0441\u0451 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c. \u041d\u043e \u043a\u0430\u043f\u0447\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442\u0441\u044f \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430. \u0421\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u0434\u043b\u044f \u043a\u0430\u043f\u0447\u0438:  <\/p>\n<pre><code class=\"cs\">  [Test]         public void Index_RegisterUserWithWrongCaptcha_ModelStateWithError()         {             \/\/init             var controller = DependencyResolver.Current.GetService&lt;Areas.Default.Controllers.UserController&gt;();             var httpContext = new MockHttpContext().Object;             ControllerContext context = new ControllerContext(new RequestContext(httpContext, new RouteData()), controller);             controller.ControllerContext = context;             controller.Session.Add(CaptchaImage.CaptchaValueKey, &quot;2222&quot;);             \/\/act             var registerUserView = new UserView()             {                 Email = &quot;user@sample.com&quot;,                 Password = &quot;123456&quot;,                 ConfirmPassword = &quot;1234567&quot;,                 AvatarPath = &quot;\/file\/no-image.jpg&quot;,                 BirthdateDay = 1,                 BirthdateMonth = 12,                 BirthdateYear = 1987,                 Captcha = &quot;1111&quot;             };              var result = controller.Register(registerUserView);             Assert.AreEqual(&quot;\u0422\u0435\u043a\u0441\u0442 \u0441 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0438 \u0432\u0432\u0435\u0434\u0435\u043d \u043d\u0435\u0432\u0435\u0440\u043d\u043e&quot;, controller.ModelState[&quot;Captcha&quot;].Errors[0].ErrorMessage);         }  <\/code><\/pre>\n<p>  \u041a\u0440\u0443\u0442\u043e!<br \/>  \u2003  <\/p>\n<h5>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438<\/h5>\n<p>  \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u0447\u0442\u043e, \u0435\u0441\u043b\u0438 \u044f \u0437\u0430\u0445\u043e\u0436\u0443 \u043d\u0435 \u043f\u043e\u0434 \u0430\u0434\u043c\u0438\u043d\u043e\u043c, \u0442\u043e \u0432 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u0447\u0430\u0441\u0442\u044c (\u0432 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440, \u043f\u043e\u043c\u0435\u0447\u0435\u043d\u043d\u044b\u0439 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u043c [Authorize(Roles=\u201cadmin\u201d)]) \u2013 \u043e\u0431\u044b\u0447\u043d\u043e\u043c\u0443 \u043f\u043e\u043b\u044c\u0432\u0430\u0442\u0435\u043b\u044e \u043d\u0435 \u0434\u0430\u0434\u0443\u0442 \u0432\u043e\u0439\u0442\u0438. \u0415\u0441\u0442\u044c \u043e\u0442\u043b\u0438\u0447\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u044d\u0442\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c. \u041e\u0431\u0440\u0430\u0442\u0438\u043c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u043a\u043b\u0430\u0441\u0441 ControllerActionInvoker \u0438 \u043e\u0442\u043d\u0430\u0441\u043b\u0435\u0434\u0443\u0435\u043c \u0435\u0433\u043e \u0434\u043b\u044f \u0432\u044b\u0437\u043e\u0432\u043e\u0432 (\/Fake\/FakeControllerActionInvoker.cs + FakeValueProvider.cs):  <\/p>\n<pre><code class=\"cs\">public class FakeValueProvider     {         protected Dictionary&lt;string, object&gt; Values { get; set; }          public FakeValueProvider()         {             Values = new Dictionary&lt;string, object&gt;();         }          public object this[string index]          {             get              {                 if (Values.ContainsKey(index))                 {                     return Values[index];                 }                 return null;             }              set             {                 if (Values.ContainsKey(index))                 {                     Values[index] = value;                 }                 else                 {                     Values.Add(index, value);                 }             }         }     }   public class FakeControllerActionInvoker&lt;TExpectedResult&gt; : ControllerActionInvoker where TExpectedResult : ActionResult     {         protected FakeValueProvider FakeValueProvider { get; set; }          public FakeControllerActionInvoker()         {             FakeValueProvider = new FakeValueProvider();         }          public FakeControllerActionInvoker(FakeValueProvider fakeValueProvider)         {             FakeValueProvider = fakeValueProvider;         }          protected override ActionExecutedContext InvokeActionMethodWithFilters(ControllerContext controllerContext, IList&lt;IActionFilter&gt; filters, ActionDescriptor actionDescriptor, IDictionary&lt;string, object&gt; parameters)         {             return base.InvokeActionMethodWithFilters(controllerContext, filters, actionDescriptor, parameters);         }          protected override object GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor)         {             var obj = FakeValueProvider[parameterDescriptor.ParameterName];             if (obj != null)             {                 return obj;             }             return parameterDescriptor.DefaultValue;         }          protected override void InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult)         {             Assert.IsInstanceOf&lt;TExpectedResult&gt;(actionResult);         }     }  <\/code><\/pre>\n<p>  \u041f\u043e \u0441\u0443\u0442\u0438 \u044d\u0442\u043e \u00ab\u0432\u044b\u0437\u044b\u0432\u0430\u043b\u044c\u0449\u0438\u043a\u00bb action-\u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u043e\u0432, \u0433\u0434\u0435 Generic \u043a\u043b\u0430\u0441\u0441 \u2013 \u044d\u0442\u043e \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0435\u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 HttpUnauthorizedResult. \u0421\u0434\u0435\u043b\u0430\u0435\u043c \u0442\u0435\u0441\u0442 (\/Test\/Admin\/HomeControllerTest.cs):  <\/p>\n<pre><code class=\"cs\">[TestFixture]     public class AdminHomeControllerTest     {         [Test]         public void Index_NotAuthorizeGetDefaultView_RedirectToLoginPage()         {             var auth = DependencyResolver.Current.GetService&lt;IAuthentication&gt;();             auth.Login(&quot;chernikov@gmail.com&quot;, &quot;password2&quot;, false);              var httpContext = new MockHttpContext(auth).Object;             var controller = DependencyResolver.Current.GetService&lt;Areas.Admin.Controllers.HomeController&gt;();             var route = new RouteData();             route.Values.Add(&quot;controller&quot;, &quot;Home&quot;);             route.Values.Add(&quot;action&quot;, &quot;Index&quot;);             route.Values.Add(&quot;area&quot;, &quot;Admin&quot;);              ControllerContext context = new ControllerContext(new RequestContext(httpContext, route), controller);             controller.ControllerContext = context;              var controllerActionInvoker = new FakeControllerActionInvoker&lt;HttpUnauthorizedResult&gt;();             var result = controllerActionInvoker.InvokeAction(controller.ControllerContext, &quot;Index&quot;);         }      } <\/code><\/pre>\n<p>  \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0442\u0435\u0441\u0442, \u043e\u043d \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442. \u0421\u0434\u0435\u043b\u0430\u0435\u043c, \u0447\u0442\u043e\u0431\u044b \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f \u0431\u044b\u043b\u0430 \u043f\u043e\u0434 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c admin \u0438 \u0431\u0443\u0434\u0435\u043c \u043e\u0436\u0438\u0434\u0430\u0442\u044c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 ViewResult:  <\/p>\n<pre><code class=\"cs\">[Test]         public void Index_AdminAuthorize_GetViewResult()         {             var auth = DependencyResolver.Current.GetService&lt;IAuthentication&gt;();             auth.Login(&quot;admin&quot;, &quot;password&quot;, false);              var httpContext = new MockHttpContext(auth).Object;             var controller = DependencyResolver.Current.GetService&lt;Areas.Admin.Controllers.HomeController&gt;();             var route = new RouteData();             route.Values.Add(&quot;controller&quot;, &quot;Home&quot;);             route.Values.Add(&quot;action&quot;, &quot;Index&quot;);             route.Values.Add(&quot;area&quot;, &quot;Admin&quot;);              ControllerContext context = new ControllerContext(new RequestContext(httpContext, route), controller);             controller.ControllerContext = context;              var controllerActionInvoker = new FakeControllerActionInvoker&lt;ViewResult&gt;();             var result = controllerActionInvoker.InvokeAction(controller.ControllerContext, &quot;Index&quot;);         }  <\/code><\/pre>\n<p>  \u0422\u0430\u043a \u0436\u0435 \u043f\u0440\u043e\u0448\u043b\u0438. \u041c\u043e\u043b\u043e\u0434\u0446\u043e\u043c. <\/p>\n<p>  \u041d\u0430 \u044d\u0442\u043e\u043c \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c\u0441\u044f \u0438 \u043f\u043e\u0434\u0443\u043c\u0430\u0435\u043c, \u0447\u0435\u0433\u043e \u043c\u044b \u0434\u043e\u0441\u0442\u0438\u0433\u043b\u0438. \u041c\u044b \u043c\u043e\u0436\u0435\u043c \u043e\u0442\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043b\u044e\u0431\u043e\u0439 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440, \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043b\u044e\u0431\u043e\u0439 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438, \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u043f\u0440\u0430\u0432 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. \u041d\u043e \u044d\u0442\u043e \u043a\u0430\u0441\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430. \u0410 \u043a\u0430\u043a \u0436\u0435 \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u043c\u043e\u0434\u0435\u043b\u044c\u044e? \u0414\u0430, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u0447\u0442\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043c\u0435\u0442\u043e\u0434 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f, \u043d\u043e \u043d\u0430 \u044d\u0442\u043e\u043c \u0432\u0441\u0451. \u0414\u0430, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c Mock-\u043c\u0435\u0442\u043e\u0434\u044b \u0434\u043b\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f, \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f, \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f, \u043d\u043e \u043a\u0430\u043a \u044d\u0442\u043e \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u0440\u0435\u0448\u0438\u0442\u044c \u0442\u0443 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443, \u043e \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u044f \u043f\u0438\u0441\u0430\u043b \u0432\u043d\u0430\u0447\u0430\u043b\u0435 \u0433\u043b\u0430\u0432\u044b? \u041a\u0430\u043a \u043c\u044b \u0437\u0430\u043c\u0435\u0442\u0438\u043c, \u0447\u0442\u043e \u0447\u0442\u043e-\u0442\u043e \u043d\u0435 \u0442\u0430\u043a \u043f\u0440\u0438 \u0443\u043f\u0443\u0449\u0435\u043d\u0438\u0438 \u043f\u043e\u043b\u044f \u0441 \u0442\u0435\u0433\u043e\u043c? \u0412 \u0445\u0440\u0435\u0441\u0442\u043e\u043c\u0430\u0442\u0438\u0439\u043d\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 NerdDinner \u0442\u0435\u0441\u0442\u044b \u043d\u0435 \u043f\u043e\u043a\u0440\u044b\u0432\u0430\u044e\u0442 \u044d\u0442\u0443 \u043e\u0431\u043b\u0430\u0441\u0442\u044c.<\/p>\n<p>  \u0415\u0441\u0442\u044c IRepository, \u0435\u0441\u0442\u044c SqlRepository, \u0435\u0441\u0442\u044c MockRepository. \u0418 \u0432\u0441\u0451 \u0447\u0442\u043e \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 SqlRepository \u2013 \u044d\u0442\u043e \u043d\u0435 \u043f\u043e\u043a\u0440\u044b\u0442\u0430\u044f \u0442\u0435\u0441\u0442\u0430\u043c\u0438 \u043e\u0431\u043b\u0430\u0441\u0442\u044c. \u0410 \u0442\u0430\u043c \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043e \u043e\u0447\u0435\u043d\u044c \u043c\u043d\u043e\u0433\u043e\u0435. \u0427\u0442\u043e \u0436\u0435 \u0434\u0435\u043b\u0430\u0442\u044c? \u041a \u0447\u0435\u043c\u0443 \u044d\u0442\u043e\u0442 TDD? <\/p>\n<h5>\u0418\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435<\/h5>\n<p>  \u0418\u0434\u0435\u044f \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u0431\u0435\u0437\u0443\u043c\u043d\u043e\u0439, \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434 \u0432 SqlRepository. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u0447\u0435\u0440\u0435\u0437 Web.config \u043d\u0430\u0445\u043e\u0434\u0438\u043c \u0431\u0430\u0437\u0443 (\u043e\u043d\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0440\u0430\u0441\u043f\u043e\u043b\u0430\u0433\u0430\u0442\u044c\u0441\u044f \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e), \u0434\u0443\u0431\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0435\u0435, \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0442\u044c\u0441\u044f \u043a \u0434\u0443\u0431\u043b\u0438\u043a\u0430\u0442\u0443 \u0411\u0414, \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442\u044c \u0442\u0435\u0441\u0442\u044b \u0438 \u0432 \u043a\u043e\u043d\u0446\u0435, \u0443\u0434\u0430\u043b\u044f\u0442\u044c \u0434\u0443\u0431\u043b\u0438\u043a\u0430\u0442 \u0411\u0414. <br \/>  \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442 LessonProject.IntegrationTest \u0432 \u043f\u0430\u043f\u043a\u0435 Test. <br \/>  \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c Ninject, Moq \u0438 NUnit:  <\/p>\n<pre><code class=\"bash\">Install-Package Ninject Install-Package Moq Install-Package NUnit  <\/code><\/pre>\n<p>  \u0422\u0430\u043a \u0436\u0435 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u0430\u043f\u043a\u0443 Sandbox \u0438 \u0432 Setup \u043d\u0430\u0441\u043b\u0435\u0434\u0443\u0435\u043c UnitTestSetupFixture (\/Setup\/IntegrationTestSetupFixture.cs) \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043f\u043e \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e \u0411\u0414:  <\/p>\n<pre><code class=\"cs\">[SetUpFixture]     public class IntegrationTestSetupFixture : UnitTestSetupFixture     {         public class FileListRestore         {             public string LogicalName { get; set; }             public string Type { get; set; }         }          protected static string NameDb = &quot;LessonProject&quot;;          protected static string TestDbName;          private void CopyDb(StandardKernel kernel, out FileInfo sandboxFile, out string connectionString)         {             var config = kernel.Get&lt;IConfig&gt;();             var db = new DataContext(config.ConnectionStrings(&quot;ConnectionString&quot;));              TestDbName = string.Format(&quot;{0}_{1}&quot;, NameDb, DateTime.Now.ToString(&quot;yyyyMMdd_HHmmss&quot;));              Console.WriteLine(&quot;Create DB = &quot; + TestDbName);             sandboxFile = new FileInfo(string.Format(&quot;{0}\\\\{1}.bak&quot;, Sandbox, TestDbName));             var sandboxDir = new DirectoryInfo(Sandbox);              \/\/backupFile             var textBackUp = string.Format(@&quot;-- Backup the database             BACKUP DATABASE [{0}]             TO DISK = '{1}'             WITH COPY_ONLY&quot;,             NameDb, sandboxFile.FullName);             db.ExecuteCommand(textBackUp);              var restoreFileList = string.Format(&quot;RESTORE FILELISTONLY FROM DISK = '{0}'&quot;, sandboxFile.FullName);             var fileListRestores = db.ExecuteQuery&lt;FileListRestore&gt;(restoreFileList).ToList();             var logicalDbName = fileListRestores.FirstOrDefault(p =&gt; p.Type == &quot;D&quot;);             var logicalLogDbName = fileListRestores.FirstOrDefault(p =&gt; p.Type == &quot;L&quot;);              var restoreDb = string.Format(&quot;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&quot;, TestDbName, sandboxFile.FullName, logicalDbName.LogicalName, logicalLogDbName.LogicalName, sandboxDir.FullName);             db.ExecuteCommand(restoreDb);              connectionString = config.ConnectionStrings(&quot;ConnectionString&quot;).Replace(NameDb, TestDbName);         }      }  <\/code><\/pre>\n<p>  \u041f\u043e \u043f\u043e\u0440\u044f\u0434\u043a\u0443: <br \/>  \u0412 \u0441\u0442\u0440\u043e\u043a\u0430\u0445   <\/p>\n<pre><code class=\"cs\">            var config = kernel.Get&lt;IConfig&gt;();             var db = new DataContext(config.ConnectionStrings(&quot;ConnectionString&quot;)); <\/code><\/pre>\n<p>   \u2014 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a \u0411\u0414.  <\/p>\n<pre><code class=\"cs\">TestDbName = string.Format(&quot;{0}_{1}&quot;, NameDb, DateTime.Now.ToString(&quot;yyyyMMdd_HHmmss&quot;)); <\/code><\/pre>\n<p>  \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u0430\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u0435 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0439 \u0411\u0414.<\/p>\n<pre><code class=\"cs\">\/\/backupFile             var textBackUp = string.Format(@&quot;-- Backup the database             BACKUP DATABASE [{0}]             TO DISK = '{1}'             WITH COPY_ONLY&quot;,             NameDb, sandboxFile.FullName);             db.ExecuteCommand(textBackUp); <\/code><\/pre>\n<p>   \u2014 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u0431\u0435\u043a\u0430\u043f \u0411\u0414 \u0432 \u043f\u0430\u043f\u043a\u0443 Sandbox.<\/p>\n<pre><code class=\"cs\">            var restoreFileList = string.Format(&quot;RESTORE FILELISTONLY FROM DISK = '{0}'&quot;, sandboxFile.FullName);             var fileListRestores = db.ExecuteQuery&lt;FileListRestore&gt;(restoreFileList).ToList();             var logicalDbName = fileListRestores.FirstOrDefault(p =&gt; p.Type == &quot;D&quot;);             var logicalLogDbName = fileListRestores.FirstOrDefault(p =&gt; p.Type == &quot;L&quot;); <\/code><\/pre>\n<p>   \u2014 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0438\u043c\u044f \u0411\u0414 \u0438 \u0444\u0430\u0439\u043b\u0430 \u043b\u043e\u0433\u043e\u0432, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043a \u043a\u043b\u0430\u0441\u0441\u0443 FIleListRestore.<\/p>\n<pre><code class=\"cs\">            var restoreDb = string.Format(&quot;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&quot;, TestDbName, sandboxFile.FullName, logicalDbName.LogicalName, logicalLogDbName.LogicalName, sandboxDir.FullName);             db.ExecuteCommand(restoreDb); <\/code><\/pre>\n<p>   \u2014 \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0411\u0414 \u043f\u043e\u0434 \u0434\u0440\u0443\u0433\u0438\u043c \u0438\u043c\u0435\u043d\u0435\u043c (TestDbName)<\/p>\n<pre><code class=\"cs\"> connectionString = config.ConnectionStrings(&quot;ConnectionString&quot;).Replace(NameDb, TestDbName); <\/code><\/pre>\n<p>   \u2014 \u043c\u0435\u043d\u044f\u0435\u043c connectionString.<\/p>\n<p>  \u0418 \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u0435\u043c \u0441\u043f\u043e\u043a\u043e\u0439\u043d\u043e \u043f\u0440\u043e\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c IRepository \u043a SqlRepository:  <\/p>\n<pre><code class=\"cs\">protected override void InitRepository(StandardKernel kernel)         {             FileInfo sandboxFile;             string connectionString;             CopyDb(kernel, out sandboxFile, out connectionString);             kernel.Bind&lt;webTemplateDbDataContext&gt;().ToMethod(c =&gt;  new webTemplateDbDataContext(connectionString));             kernel.Bind&lt;IRepository&gt;().To&lt;SqlRepository&gt;().InTransientScope();             sandboxFile.Delete();         } <\/code><\/pre>\n<p>  \u0418\u0442\u0430\u043a, \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c sandboxFile \u2013 \u044d\u0442\u043e \u0444\u0430\u0439\u043b \u0431\u0435\u043a\u0430\u043f\u0430, \u0438 connectionString \u2013 \u044d\u0442\u043e \u043d\u043e\u0432\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f (\u043a \u0434\u0443\u0431\u043b\u0438\u043a\u0430\u0442\u0443 \u0411\u0414). \u041c\u044b \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u0411\u0414, \u0441\u0432\u044f\u0437\u044b\u0432\u0430\u0435\u043c \u0438\u043c\u0435\u043d\u043d\u043e \u0441 SqlRepository, \u043d\u043e \u0431\u0430\u0437\u0443 \u043f\u043e\u0434\u0441\u043e\u0432\u044b\u0432\u0430\u0435\u043c \u043d\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u0443\u044e. \u0418 \u0441 \u043d\u0435\u0439 \u043c\u043e\u0436\u043d\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0432\u0441\u0451 \u0447\u0442\u043e \u0443\u0433\u043e\u0434\u043d\u043e. \u0424\u0430\u0439\u043b \u0431\u0435\u043a\u0430\u043f\u0430 \u0431\u0430\u0437\u044b \u0432 \u043a\u043e\u043d\u0446\u0435 \u0443\u0434\u0430\u043b\u044f\u0435\u043c.<br \/>  \u0418 \u0434\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0443\u0436\u0435 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0439 \u0411\u0414, \u043f\u043e\u0441\u043b\u0435 \u043f\u0440\u043e\u0433\u043e\u043d\u0430 \u0432\u0441\u0435\u0445 \u0442\u0435\u0441\u0442\u043e\u0432:  <\/p>\n<pre><code class=\"cs\">private void RemoveDb()         {             var config =  DependencyResolver.Current.GetService&lt;IConfig&gt;();              var db = new DataContext(config.ConnectionStrings(&quot;ConnectionString&quot;));              var textCloseConnectionTestDb = string.Format(@&quot;ALTER DATABASE [{0}] SET SINGLE_USER WITH ROLLBACK IMMEDIATE&quot;, TestDbName);             db.ExecuteCommand(textCloseConnectionTestDb);              var textDropTestDb = string.Format(@&quot;DROP DATABASE [{0}]&quot;, TestDbName);             db.ExecuteCommand(textDropTestDb);         } <\/code><\/pre>\n<p>  \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f TestDbName, \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u0435\u043c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 (\u0430 \u0442\u043e \u043e\u043d\u043e \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0435), \u0438 \u0443\u0434\u0430\u043b\u044f\u0435\u043c \u0431\u0430\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445.<br \/>  \u041d\u0435 \u0437\u0430\u0431\u044b\u0432\u0430\u0435\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043a\u043e\u043f\u0438\u044e Web.config:  <\/p>\n<pre><code class=\"bash\">xcopy $(SolutionDir)LessonProject\\Web.config $(ProjectDir)Sandbox\\ \/y <\/code><\/pre>\n<p>  \u041d\u043e \u043a\u0441\u0442\u0430\u0442\u0438, \u0438\u043d\u043e\u0433\u0434\u0430 \u0411\u0414 \u043d\u0435\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0443\u0434\u0430\u043b\u044f\u0442\u044c. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0431\u0430\u0437\u0443 \u043a\u0443\u0447\u0435\u0439 \u0434\u0430\u043d\u043d\u044b\u0445 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043f\u043e\u0438\u0441\u043a \u0438\u043b\u0438 \u043f\u0435\u0439\u0434\u0436\u0438\u043d\u0433. \u042d\u0442\u043e \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0438\u0436\u0435. \u0410 \u0441\u0435\u0439\u0447\u0430\u0441 \u0442\u0435\u0441\u0442 \u2013 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0432 \u0411\u0414 \u0437\u0430\u043f\u0438\u0441\u0438:  <\/p>\n<pre><code class=\"cs\">[TestFixture]     public class DefaultUserControllerTest     {         [Test]         public void CreateUser_CreateNormalUser_CountPlusOne()         {             var repository = DependencyResolver.Current.GetService&lt;IRepository&gt;();              var controller = DependencyResolver.Current.GetService&lt;LessonProject.Areas.Default.Controllers.UserController&gt;();              var countBefore = repository.Users.Count();             var httpContext = new MockHttpContext().Object;              var route = new RouteData();              route.Values.Add(&quot;controller&quot;, &quot;User&quot;);             route.Values.Add(&quot;action&quot;, &quot;Register&quot;);             route.Values.Add(&quot;area&quot;, &quot;Default&quot;);              ControllerContext context = new ControllerContext(new RequestContext(httpContext, route), controller);             controller.ControllerContext = context;              controller.Session.Add(CaptchaImage.CaptchaValueKey, &quot;1111&quot;);              var registerUserView = new UserView()             {                 ID = 0,                 Email = &quot;rollinx@gmail.com&quot;,                 Password = &quot;123456&quot;,                 ConfirmPassword = &quot;123456&quot;,                 Captcha = &quot;1111&quot;,                 BirthdateDay = 13,                 BirthdateMonth = 9,                 BirthdateYear = 1970             };              Validator.ValidateObject&lt;UserView&gt;(registerUserView);             controller.Register(registerUserView);              var countAfter = repository.Users.Count();             Assert.AreEqual(countBefore + 1, countAfter);         }     } <\/code><\/pre>\n<p>  \u041f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435, \u0447\u0442\u043e \u043d\u0435\u0442 \u0432 \u0411\u0414 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0441 \u0442\u0430\u043a\u0438\u043c email.<br \/>  \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c. \u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442. \u041a\u0430\u0439\u0444! \u0422\u0443\u0442 \u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u043a\u0430\u043a\u0438\u0435 \u043c\u043e\u0449\u043d\u043e\u0441\u0442\u0438 \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u044e\u0442\u0441\u044f. \u0418 \u0435\u0441\u043b\u0438 \u044e\u043d\u0438\u0442-\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u2013 \u044d\u0442\u043e \u043a\u0430\u043a \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0445 \u043a\u0443\u0441\u043e\u0447\u043a\u043e\u0432 \u043a\u043e\u0434\u0430, \u0430 \u0442\u0443\u0442 \u2013 \u044d\u0442\u043e \u0446\u0435\u043b\u044b\u0439 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439. \u041d\u043e, \u043a\u0441\u0442\u0430\u0442\u0438, \u0437\u0430\u043c\u0435\u0447\u0443, \u0447\u0442\u043e MailNotify \u0432\u0441\u0451 \u0436\u0435 \u0432\u044b\u0441\u044b\u043b\u0430\u0435\u0442 \u043f\u0438\u0441\u044c\u043c\u0430 \u043d\u0430 \u043f\u043e\u0447\u0442\u0443. \u0422\u0430\u043a \u0447\u0442\u043e \u043f\u0435\u0440\u0435\u043f\u0438\u0448\u0435\u043c \u0435\u0433\u043e \u043a\u0430\u043a \u0441\u0435\u0440\u0432\u0438\u0441:<br \/>  \/LessonProject\/Tools\/Mail\/IMailSender.cs:  <\/p>\n<pre><code class=\"cs\">public interface IMailSender     {         void SendMail(string email, string subject, string body, MailAddress mailAddress = null);     } <\/code><\/pre>\n<p>  \/LessonProject\/Tools\/Mail\/MailSender.cs:  <\/p>\n<pre><code class=\"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(&quot;Email : {0} {1} \\t Subject: {2} {3} Body: {4}&quot;, email, Environment.NewLine, subject, Environment.NewLine, body);                 }             }             catch (Exception ex)             {                 logger.Error(&quot;Mail send exception&quot;, ex.Message);             }         }     } <\/code><\/pre>\n<p>  \u2003<br \/>  \/LessonProject\/Tools\/Mail\/NotifyMail.cs:  <\/p>\n<pre><code class=\"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&lt;IConfig&gt;();                  }                 return _config;             }         }          private static IMailSender _mailSender;          public static IMailSender MailSender         {             get             {                 if (_mailSender == null)                 {                     _mailSender = (DependencyResolver.Current).GetService&lt;IMailSender&gt;();                  }                 return _mailSender;             }         }          public static void SendNotify(string templateName, string email,             Func&lt;string, string&gt; subject,             Func&lt;string, string&gt; body)         {             var template = Config.MailTemplates.FirstOrDefault(p =&gt; string.Compare(p.Name, templateName, true) == 0);             if (template == null)             {                 logger.Error(&quot;Can't find template (&quot; + templateName + &quot;)&quot;);             }             else             {                 MailSender.SendMail(email,                     subject.Invoke(template.Subject),                     body.Invoke(template.Template));             }         }     }  <\/code><\/pre>\n<p>  \/LessonProject\/App_Start\/NinjectWebCommon.cs:  <\/p>\n<pre><code class=\"cs\">private static void RegisterServices(IKernel kernel)         {\u2026 kernel.Bind&lt;IMailSender&gt;().To&lt;MailSender&gt;();         }         <\/code><\/pre>\n<p>  \u041d\u0443 \u0438 \u0432 LessonProject.UnitTest \u0434\u043e\u0431\u0430\u0432\u0438\u043c MockMailSender (\/Mock\/Mail\/MockMailSender.cs):  <\/p>\n<pre><code class=\"cs\">public class MockMailSender : Mock&lt;IMailSender&gt;      {         public MockMailSender(MockBehavior mockBehavior = MockBehavior.Strict)             : base(mockBehavior)         {             this.Setup(p =&gt; p.SendMail(It.IsAny&lt;string&gt;(), It.IsAny&lt;string&gt;(), It.IsAny&lt;string&gt;(), It.IsAny&lt;MailAddress&gt;()))                 .Callback((string email, string subject, string body, MailAddress address) =&gt;                 Console.WriteLine(String.Format(&quot;Send mock email to: {0}, subject {1}&quot;, email, subject)));         }     } <\/code><\/pre>\n<p>  \u0412 UnitTestSetupFixture.cs (\/LessonProject.UnitTest\/Setup\/UnitTestSetupFixture.cs):  <\/p>\n<pre><code class=\"cs\">protected virtual IKernel InitKernel()         { \u2026 kernel.Bind&lt;MockMailSender&gt;().To&lt;MockMailSender&gt;();             kernel.Bind&lt;IMailSender&gt;().ToMethod(p =&gt; kernel.Get&lt;MockMailSender&gt;().Object);             return kernel;         }  <\/code><\/pre>\n<p>  \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c, \u0442\u0435\u0441\u0442\u044b \u043f\u0440\u043e\u0439\u0434\u0435\u043d\u044b, \u043d\u043e \u043d\u0430 \u043f\u043e\u0447\u0442\u0443 \u0443\u0436\u0435 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f.  <\/p>\n<pre><code class=\"bash\">=============== =====START===== =============== Create DB = LessonProject_20130314_104218 Send mock email to: chernikov@googlemail.com, subject \u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u043d\u0430   =============== =====BYE!====== =============== <\/code><\/pre>\n<h5>\u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445<\/h5>\n<p>  \u041a\u0440\u043e\u043c\u0435 \u0432\u0441\u0435\u0433\u043e \u043f\u0440\u043e\u0447\u0435\u0433\u043e, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438 \u043d\u0435 \u0443\u0434\u0430\u043b\u044f\u0442\u044c \u0431\u0430\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u0441\u043b\u0435 \u043f\u0440\u043e\u0431\u0435\u0433\u043e\u0432 \u0442\u0435\u0441\u0442\u0430. (\u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u0442\u044c)\u042f \u0434\u043e\u0431\u0430\u0432\u043b\u044e GenerateData \u043f\u0440\u043e\u0435\u043a\u0442 \u0432 \u043f\u0430\u043f\u043a\u0443 Test, \u043d\u043e \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u043c\u044b \u0435\u0433\u043e \u043d\u0435 \u0431\u0443\u0434\u0435\u043c, \u043f\u0440\u043e\u0441\u0442\u043e \u0447\u0442\u043e\u0431\u044b \u0431\u044b\u043b. \u041e\u043d \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u044b\u0439. \u0421\u0443\u0442\u044c \u0435\u0433\u043e \u2013 \u0435\u0441\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u044f, \u0438 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0438\u0445 \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0444\u0430\u043c\u0438\u043b\u0438\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0444\u0430\u043c\u0438\u043b\u0438\u0438 \u0430\u043c\u0435\u0440\u0438\u043a\u0430\u043d\u0441\u043a\u0438\u0445 \u043f\u0440\u0435\u0437\u0438\u0434\u0435\u043d\u0442\u043e\u0432 (\u0437\u043d\u0430\u044f \u0438\u0445, \u043c\u044b \u0441\u0440\u0430\u0437\u0443 \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u043c \u0438\u0445 \u043e\u0442 \u0434\u0440\u0443\u0433\u0438\u0445 \u0444\u0430\u043c\u0438\u043b\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u043a\u043e\u0440\u0435\u0435 \u0431\u0443\u0434\u0443\u0442 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u043c\u0438). <\/p>\n<p>  \u042d\u0442\u043e \u0442\u0430\u043a\u0436\u0435 \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u00ab\u044d\u0444\u0444\u0435\u043a\u0442\u0430 \u0440\u044b\u0431\u044b\u00bb, \u043a\u043e\u0433\u0434\u0430 \u0432 \u0448\u0430\u0431\u043b\u043e\u043d\u0435 \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0431\u044b\u043b\u0438 \u043e\u0434\u043d\u043e\u0439 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439, \u043d\u043e \u043d\u0435 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0439 \u0434\u043b\u0438\u043d\u044b \u0438 \u0448\u0430\u0431\u043b\u043e\u043d \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u043b \u043f\u0440\u0438\u043b\u0438\u0447\u043d\u043e, \u043d\u043e \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432\u0441\u0451 \u043f\u043e\u0435\u0445\u0430\u043b\u043e.<br \/>  \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c 100 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0438 \u043f\u043e\u0442\u043e\u043c \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u043d\u0438\u0445:  <\/p>\n<pre><code class=\"cs\">[Test]         public void CreateUser_Create100Users_NoAssert()         {             var repository = DependencyResolver.Current.GetService&lt;IRepository&gt;();             var controller = DependencyResolver.Current.GetService&lt;LessonProject.Areas.Default.Controllers.UserController&gt;();              var httpContext = new MockHttpContext().Object;              var route = new RouteData();              route.Values.Add(&quot;controller&quot;, &quot;User&quot;);             route.Values.Add(&quot;action&quot;, &quot;Register&quot;);             route.Values.Add(&quot;area&quot;, &quot;Default&quot;);              ControllerContext context = new ControllerContext(new RequestContext(httpContext, route), controller);             controller.ControllerContext = context;              controller.Session.Add(CaptchaImage.CaptchaValueKey, &quot;1111&quot;);              var rand = new Random((int)DateTime.Now.Ticks);             for (int i = 0; i &lt; 100; i++)             {                 var registerUserView = new UserView()                 {                     ID = 0,                     Email = Email.GetRandom(Name.GetRandom(), Surname.GetRandom()),                     Password = &quot;123456&quot;,                     ConfirmPassword = &quot;123456&quot;,                     Captcha = &quot;1111&quot;,                     BirthdateDay = rand.Next(28) + 1,                     BirthdateMonth = rand.Next(12) + 1,                     BirthdateYear = 1970 + rand.Next(20)                 };                  controller.Register(registerUserView);             }         }  <\/code><\/pre>\n<p>  \u0412 IntegrationTestSetupFixture.cs \u043e\u0442\u043a\u043b\u044e\u0447\u0438\u043c \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0411\u0414 \u043f\u043e\u0441\u043b\u0435 \u0440\u0430\u0431\u043e\u0442\u044b (\/Setup\/IntegrationTestSetupFixture.cs):<\/p>\n<pre><code class=\"cs\">        protected static bool removeDbAfter = false; <\/code><\/pre>\n<p>  \u0412 Web.config \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0441 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0439 \u0411\u0414:  <\/p>\n<pre><code class=\"cs\">&lt;add name=&quot;ConnectionString&quot; connectionString=&quot;Data Source=SATURN-PC;Initial Catalog=LessonProject_20130314_111020;Integrated Security=True;Pooling=False&quot; providerName=&quot;System.Data.SqlClient&quot; \/&gt;  <\/code><\/pre>\n<p>  \u0418 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u0441\u0430\u0439\u0442:<br \/>  <img decoding=\"async\" src=\"http:\/\/habrastorage.org\/storage2\/bff\/a18\/263\/bffa182638e5c499ceed9499c5da1a0c.jpg\"\/><\/p>\n<h5>\u0418\u0442\u043e\u0433<\/h5>\n<p>  \u0412 \u044d\u0442\u043e\u043c \u0443\u0440\u043e\u043a\u0435 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438:  <\/p>\n<ul>\n<li>\u041f\u0440\u0438\u043d\u0446\u0438\u043f\u044b TDD \u0438 \u043a\u043e\u0433\u0434\u0430 \u043e\u043d\u0438 \u043d\u0435 \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0442<\/li>\n<li>NUnit \u0438 \u043a\u0430\u043a \u0441 \u043d\u0438\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c<\/li>\n<li>Mock \u0438 \u043a\u0430\u043a \u0441 \u043d\u0438\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c <\/li>\n<li>Unit-\u0442\u0435\u0441\u0442\u044b \u0438 \u043a\u0430\u043a \u044d\u0442\u043e\u0442 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c \u043d\u0430\u043c \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043e\u0434\u0430<\/li>\n<li>Integration-\u0442\u0435\u0441\u0442\u044b, \u0438 \u043a\u0430\u043a \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c<\/li>\n<\/ul>\n<p>  \u0422\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u2013 \u044d\u0442\u043e \u043e\u0447\u0435\u043d\u044c \u0431\u043e\u043b\u044c\u0448\u0430\u044f \u043e\u0431\u043b\u0430\u0441\u0442\u044c, \u044d\u0442\u043e \u0434\u0430\u0436\u0435 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0430\u044f \u043f\u0440\u043e\u0444\u0435\u0441\u0441\u0438\u044f \u0438 \u0441\u043a\u043b\u0430\u0434 \u0443\u043c\u0430 (\u043d\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u0441\u043a\u0438\u0439). \u0418 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043e\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u0432\u0438\u0441\u0435\u0442\u044c \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0439, \u0445\u043e\u0442\u044f, \u0431\u0435\u0441\u0441\u043f\u043e\u0440\u043d\u043e, \u0441\u043e\u0431\u043b\u044e\u0434\u0435\u043d\u0438\u0435 \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u043e\u0432 TDD \u0438 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0445 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0432 \u043f\u0440\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430 \u043e\u0448\u0438\u0431\u043e\u043a. \u041d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0442\u0435\u0441\u0442\u043e\u0432 \u2013 \u043d\u0435 \u043f\u0430\u043d\u0430\u0446\u0435\u044f \u043e\u0442 \u0432\u0441\u0435\u0445 \u0431\u0435\u0434, \u044d\u0442\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442, \u0438 \u0432\u0430\u0436\u043d\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0438\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f\u2026 <br \/>  \u041c\u044b \u043e\u0431\u043e\u0448\u043b\u0438 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435\u043c \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u0439 \u0447\u0430\u0441\u0442\u0438, \u0438 \u0447\u0435\u0441\u0442\u043d\u043e \u0433\u043e\u0432\u043e\u0440\u044f, \u044f \u043d\u0435 \u0437\u043d\u0430\u044e, \u043a\u0430\u043a \u044d\u0442\u043e \u0434\u043e\u043b\u0436\u043d\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442\u044c. \u0412 JQuery \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u043e\u043a\u0442\u044f\u0431\u0440\u0435 2011\u0433\u043e \u043d\u0430\u0447\u0430\u043b\u0438 \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442 qUnit, \u043d\u043e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043f\u043e \u043d\u0435\u043c\u0443 \u043f\u043e\u0447\u0442\u0438 \u043d\u0435\u0442.<\/p>\n<p>  \u0412\u0441\u0435 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438 \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0443 <a href=\"https:\/\/bitbucket.org\/chernikov\/lessons\">https:\/\/bitbucket.org\/chernikov\/lessons<\/a><\/li>\n<\/ul>\n<div class=\"clear\"><\/div>\n<\/p><\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"http:\/\/habrahabr.ru\/post\/176137\/\"> http:\/\/habrahabr.ru\/post\/176137\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"content html_format\">   \t<b>\u0426\u0435\u043b\u044c \u0443\u0440\u043e\u043a\u0430.<\/b> \u041d\u0430\u0443\u0447\u0438\u0442\u044c\u0441\u044f \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0442\u0435\u0441\u0442\u044b \u0434\u043b\u044f \u043a\u043e\u0434\u0430. NUnit. \u041f\u0440\u0438\u043d\u0446\u0438\u043f \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f TDD. Mock. \u042e\u043d\u0438\u0442-\u0442\u0435\u0441\u0442\u044b. \u0418\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435. \u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<h5>\u0422\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435, \u043f\u0440\u0438\u043d\u0446\u0438\u043f TDD, \u044e\u043d\u0438\u0442-\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u043f\u0440\u043e\u0447\u0435\u0435.<\/h5>\n<p>  \u0422\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0434\u043b\u044f \u043c\u0435\u043d\u044f \u043b\u0438\u0447\u043d\u043e \u2013 \u044d\u0442\u043e \u0442\u0435\u043c\u0430 \u043c\u043d\u043e\u0433\u0438\u0445 \u0440\u0430\u0437\u043c\u044b\u0448\u043b\u0435\u043d\u0438\u0439. \u041d\u0443\u0436\u043d\u044b \u0438\u043b\u0438 \u043d\u0435 \u043d\u0443\u0436\u043d\u044b \u0442\u0435\u0441\u0442\u044b? \u041d\u043e \u043d\u0438\u043a\u0442\u043e \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0441\u043f\u043e\u0440\u0438\u0442\u044c, \u0447\u0442\u043e \u0434\u043b\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0442\u0435\u0441\u0442\u043e\u0432 \u043d\u0443\u0436\u043d\u044b \u0440\u0435\u0441\u0443\u0440\u0441\u044b. <br \/>  \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0434\u0432\u0430 \u0441\u043b\u0443\u0447\u0430\u044f:  <\/p>\n<ol>\n<li>\u041c\u044b \u0434\u0435\u043b\u0430\u0435\u043c \u0441\u0430\u0439\u0442, \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0437\u0430\u043a\u0430\u0437\u0447\u0438\u043a\u0443, \u043e\u043d \u0432\u044b\u0441\u044b\u043b\u0430\u0435\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u043d\u0435\u0442\u043e\u0447\u043d\u043e\u0441\u0442\u0435\u0439 \u0438 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043f\u043e\u0436\u0435\u043b\u0430\u043d\u0438\u0439, \u043c\u044b \u0438\u0445 \u0431\u043e\u0434\u0440\u043e \u043f\u0440\u0430\u0432\u0438\u043c \u0438 \u0441\u0430\u0439\u0442 \u043e\u0442\u0434\u0430\u0435\u043c \u0437\u0430\u043a\u0430\u0437\u0447\u0438\u043a\u0443, \u0442.\u0435. \u0432\u044b\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u043c \u043d\u0430 \u0435\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440. \u041d\u0430 \u0435\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440 \u043d\u0438\u043a\u0442\u043e \u043d\u0435 \u0445\u043e\u0434\u0438\u0442, \u0437\u0430\u043a\u0430\u0437\u0447\u0438\u043a \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u0442, \u0447\u0442\u043e \u0447\u0443\u0434\u0430 \u043d\u0435 \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u043e \u0438 \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u0435\u0442 \u043f\u043b\u0430\u0442\u0438\u0442\u044c \u0437\u0430 \u0445\u043e\u0441\u0442\u0438\u043d\u0433\/\u0434\u043e\u043c\u0435\u043d. \u0421\u0430\u0439\u0442 \u0443\u043c\u0438\u0440\u0430\u0435\u0442. \u041d\u0443\u0436\u043d\u044b \u043b\u0438 \u0442\u0430\u043c \u0442\u0435\u0441\u0442\u044b?<\/li>\n<li>\u041c\u044b \u0434\u0435\u043b\u0430\u0435\u043c \u0441\u0430\u0439\u0442, \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0437\u0430\u043a\u0430\u0437\u0447\u0438\u043a\u0443, \u043e\u043d \u0432\u044b\u0441\u044b\u043b\u0430\u0435\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u043f\u0440\u0430\u0432\u043e\u043a, \u043c\u044b \u0438\u0445 \u0431\u043e\u0434\u0440\u043e \u043f\u0440\u0430\u0432\u0438\u043c, \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0441\u0430\u0439\u0442. \u0427\u0435\u0440\u0435\u0437 \u043f\u043e\u043b\u0433\u043e\u0434\u0430 \u043d\u0430 \u0441\u0430\u0439\u0442\u0435 300 \u0443\u043d\u0438\u043a\u043e\u0432 \u0432 \u0434\u0435\u043d\u044c \u0438 \u044d\u0442\u0430 \u0446\u0438\u0444\u0440\u0430 \u0440\u0430\u0441\u0442\u0435\u0442 \u0438\u0437\u043e \u0434\u043d\u044f \u0432 \u0434\u0435\u043d\u044c. \u0417\u0430\u043a\u0430\u0437\u0447\u0438\u043a \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u043f\u0440\u043e\u0441\u0438\u0442 \u043d\u043e\u0432\u044b\u0435 \u0444\u0438\u0447\u0438, \u0441\u0442\u0430\u0440\u044b\u0439 \u043a\u043e\u0434 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0440\u0430\u0437\u0440\u0430\u0441\u0442\u0430\u0442\u044c\u0441\u044f, \u0438 \u0441\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0435\u043c \u0435\u0433\u043e \u0432\u0441\u0451 \u0441\u043b\u043e\u0436\u043d\u0435\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c. <\/li>\n<\/ol>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-176137","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/176137","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=176137"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/176137\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=176137"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=176137"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=176137"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}