I am fan of
TDD principle, and always trying to write tests first. Today I want to show,
how I usually test Web API controller. There are two approaches:
1. Unit test
Consider
UserController class, which has POST method that registers users.
public class UserController : ApiController
{
private readonly IRegistrationService registrationService;
public
UserController(IRegistrationService registrationService)
{
this.registrationService = registrationService;
}
public HttpResponseMessage Post([FromBody]string json)
{
var model = new JavaScriptSerializer().Deserialize<RegistrationModel>(json);
bool success = this.registrationService.Register(model);
return new HttpResponseMessage(success ? HttpStatusCode.OK : HttpStatusCode.InternalServerError);
}
And test
(which, of course, was written first)
[Test]
public void TestUserCanBeRegistered()
{
// Arrange
var
registrationService = new Mock<IRegistrationService>();
registrationService
.Setup(x => x.Register(It.IsAny<RegistrationModel>()))
.Returns(true);
var
userController = new UserController(registrationService.Object);
// Act
var response = userController.Post(@"{""login"":""Alex"", ""password"": ""password""}");
// Assert
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
}
Test runs
OK
BUT if you
try to send real request through the fiddler, for example, you will get an error.
Content-Type:
application/json; charset=utf-8
Content-Length:
40
{"login":"Alex",
"password": "password"}
HTTP/1.1 500 Internal Server Error
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json;
charset=utf-8
Expires: -1
Server: Microsoft-IIS/10.0
X-AspNet-Version: 4.0.30319
X-SourceFiles:
=?UTF-8?B?RTpcVGVtcFxXZWJBcHBcV2ViQXBwXHVzZXJc?=
X-Powered-By: ASP.NET
Date: Thu, 12 Jan 2017 12:57:07 GMT
Content-Length: 2339
{"Message":"An
error has occurred.","ExceptionMessage":"Value
cannot be null.\r\nParameter name: input","ExceptionType":"System.ArgumentNullException","StackTrace":" at System.Web.Script.Serialization.JavaScriptSerializer.Deserialize(JavaScriptSerializer
serializer, String input, Type type, Int32 depthLimit)
How we can
get it, if test passed OK? This happens, because we fill method parameters by
ourselves, not by real request. Error in
tests costs much more than in the code, that's why I prefer another method of
controller testing
2. Integration test*
Let’s test it in the other manner.
First, we need to add some references to our project with tests.
First, we need to add some references to our project with tests.
Install-Package
Microsoft.Owin.Host.SystemWeb
Install-Package
Microsoft.AspNet.WebApi.Owin
Install-Package
Microsoft.AspNet.WebApi.OwinSelfHost
Install-Package
Microsoft.Owin.Testing
Install-Package Unity
For our convenience we create base class for
integration tests
internal class IntegrationTestBase
{
protected TestServer Server { get; private set; }
[TestFixtureSetUp]
public void BindServices()
{
this.Server = TestServer.Create<TestStartup>();
}
[TestFixtureTearDown]
public void DisposeServer()
{
this.Server.Dispose();
}
}
TestStartup.cs. If you are hosting
your application with OWIN you can use Startup.cs here.
public class TestStartup
{
public void Configuration(IAppBuilder builder)
{
config.Routes.MapHttpRoute("users", "users", new { controller = "User" });
var container = new UnityContainer();
container.RegisterType<IRegistrationService, RegistrationService>();
config.DependencyResolver = new UnityResolver(container);
builder.UseWebApi(config);
}
}
And finally write new test using
OWIN TestServer that will be hosted InProc.
[Test]
public async void TestRequestWasMappedCorrectlyAndUserRegistered()
{
// Arrange
using (var client = new HttpClient(this.Server.Handler))
{
var body = new StringContent(@"{""login"":""Alex"", ""password"": ""password""}", Encoding.UTF8, "application/json");
// Act
var response = await client.PostAsync("http://api.webapp.com/users/", body);
// Assert
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
}
This approach simulates real request to the API resource from the client. Test didn’t pass. Now this correlates with the real behavior. Time to “green” this test. There are many ways to do it:
1. Change type
of the input parameter to HttpRequestMessage
public HttpResponseMessage Post(HttpRequestMessage request) { … }
and then
gets the content
string body =
message.Content.ReadAsStringAsync().Result;
2. Change
type of the input parameter to IDictionary<string, string> (using
IDictionary<string, object> is not recommended)
public HttpResponseMessage Post(IDictionary<string, string> dict) { … }
3. Or
specify concrete type RegistrationModel
4. Or vice versa
make it more generic with dynamic
public HttpResponseMessage Post([FromBody]dynamic obj) { … }
I chose
third variant, so our controller method will look like
public HttpResponseMessage Post(RegistrationModel model)
{
bool success = this.registrationService.Register(model);
return new HttpResponseMessage(success ? HttpStatusCode.OK : HttpStatusCode.InternalServerError);
}
Now all
tests pass OK (of course we should fix test ‘TestUserCanBeRegistered’, because
we changed the contract).
Example of the code available on github
* - I name it integration, because it checks not only controller class but also MediaTypeFormatter
Pretty blog, so many ideas in a single site, thanks for the informative article, keep updating more article.
ReplyDeleteSoftware testing course in chennai
Great Article Journal Paper Writing Services projects for cse JavaScript Training in Chennai JavaScript Training in Chennai
DeleteLearned a lot from your post and it is really good. Share more tech updates regularly.
ReplyDeleteui ux design course in Chennai
ui design course in chennai
ui developer course in chennai
Ethical Hacking course in Chennai
Web Designing Course in chennai
Web development training in chennai
PHP Training in Chennai
ui ux design course in Anna Nagar
ui ux design course in Vadapalani
ui ux design course in Thiruvanmiyur
This stays as one of the best and attractive post I have read yet. Great sharing this post.
ReplyDeleteEducation Franchise India
Spoken English Franchise
Franchise For Spoken English Classes
Top Education Franchise In India
Best Education Franchise In India
Computer Education Franchise
Education Franchise India
Computer Center Franchise
Education Franchise Opportunities In India
thanks for your details it's very use for my works web design company in velachery
ReplyDeleteDelhi Agra Jaipur Tour by Bus
ReplyDeleteDelhi to Jaipur Same Day Tour
Delhi One Day Tour Package
Delhi Sightseeing One Day
Delhi Sightseeing Tour by Bus
Delhi Jaipur One Day Tour Package
Haridwar, Rishikesh Tours by Volvo
adanaescort01.com - adiyamanescortxx.com - afyonarackiralama.net - aksarayescort.net - antalyaoyunpark.com - aydinescortkiz.com - balikesirescortlar.com - batmanescortlar.com - bitlisescortlar.com - burdurescortlar.com - bursamalaysias.com - diyarbakirambar.com - edirnedespor.com - erzurumyolkosusu.com - eskisehirescortlari.com - gaziantepekspres.org - gebzeescortkiz.com - giresunmaraton.com - hataykoleji.com - ispartakpss.com - karabukteknik.com - kastamonuajans.net - kayserivalisi.com - kilisescort.com - kocaeliescortlar.com - konyaescortlar.com - kutahyaizemlak.com - malatyadataksi.com - manisaescortlar.com - marasatasoyemlak.com - mardinfanatik.com - mersinmoda.com - muglaapart.net - nigdeyapi.com - orduescortt.com - osmaniyeyorum.com - sakaryanur.com - samsunescortlar.com - siirteyatirim.com - sincanoto.com - tekirdagescortlar.com - tokatforum.com - usakbasin.com - vanescortilan.com - yalovadaemlak.com - yozgattanal.com - sanliurfadayim.com - zonguldakescort.com
ReplyDeleteno deposit bonus forex 2021 - takipçi satın al - takipçi satın al - takipçi satın al - tiktok takipçi satın al - instagram beğeni satın al - instagram beğeni satın al - google haritalara yer ekleme - btcturk - tiktok izlenme satın al - sms onay - izlenme-satin-al.com/youtube - google haritalara yer ekleme - no deposit bonus forex 2021 - tiktok jeton hilesi - tiktok beğeni satın al - binance - takipçi satın al - uc satın al - finanspedia.com - sms onay - sms onay - tiktok takipçi satın al - tiktok beğeni satın al - twitter takipçi satın al - trend topic satın al - youtube abone satın al - instagram beğeni satın al - tiktok beğeni satın al - twitter takipçi satın al - trend topic satın al - youtube abone satın al - instagram beğeni satın al - tiktok takipçi satın al - tiktok beğeni satın al - twitter takipçi satın al - trend topic satın al - youtube abone satın al - instagram beğeni satın al - perde modelleri - instagram takipçi satın al - instagram takipçi satın al - cami avizesi - marsbahis
ReplyDeleteinstagram takipçi satın al
ReplyDeleteinstagram takipçi satın al
takipçi satın al
instagram takipçi satın al
instagram takipçi satın al
takipçi satın al
instagram takipçi satın al
aşk kitapları
tiktok takipçi satın al
instagram beğeni satın al
youtube abone satın al
twitter takipçi satın al
tiktok beğeni satın al
tiktok izlenme satın al
twitter takipçi satın al
tiktok takipçi satın al
youtube abone satın al
tiktok beğeni satın al
instagram beğeni satın al
trend topic satın al
trend topic satın al
youtube abone satın al
beğeni satın al
tiktok izlenme satın al
sms onay
youtube izlenme satın al
tiktok beğeni satın al
sms onay
sms onay
perde modelleri
instagram takipçi satın al
takipçi satın al
tiktok jeton hilesi
pubg uc satın al
sultanbet
marsbahis
betboo
betboo
betboo
takipçi satın al
ReplyDeleteinstagram takipçi satın al
https://www.takipcikenti.com
Thank you for sharing this valuable information with us.
ReplyDeleteThirukkural pdf download
Sai Satcharitra in malayalam pdf
Sai Satcharitra in marathi pdf
Sai Satcharitra in kannada pdf
Sai Satcharitra in bengali pdf
Sai Satcharitra in gujarati pdf
seo fiyatları
ReplyDeletesaç ekimi
dedektör
instagram takipçi satın al
ankara evden eve nakliyat
fantezi iç giyim
sosyal medya yönetimi
mobil ödeme bozdurma
kripto para nasıl alınır
instagram beğeni satın al
ReplyDeleteyurtdışı kargo
seo fiyatları
saç ekimi
dedektör
fantazi iç giyim
sosyal medya yönetimi
farmasi üyelik
mobil ödeme bozdurma
Much obliged for sharing this brilliant substance. its extremely fascinating. Numerous web journals I see these days don't actually give whatever pulls in others however the manner in which you have plainly clarified everything it's truly awesome. There are loads of posts But your method of Writing is so Good and Knowledgeable. continue to post such helpful data and view my site too...
ReplyDeleteHow to make a paper airplane | Origami paper plane | Boomerang Airplane | how to make a eagle paper airplane | Best paper airplane design for distance and speed | Nakamura lock paper airplane
Eagle paper plane | Zazoom | Easy Freezy | Fold n fly
bitcoin nasıl alınır
ReplyDeletetiktok jeton hilesi
youtube abone satın al
gate io güvenilir mi
referans kimliği nedir
tiktok takipçi satın al
bitcoin nasıl alınır
mobil ödeme bozdurma
mobil ödeme bozdurma
smm panel
ReplyDeletesmm panel
iş ilanları
İnstagram Takipçi Satın Al
hırdavatçı burada
Www.beyazesyateknikservisi.com.tr
Servis
tiktok jeton hilesi