SlideShare a Scribd company logo
Developing in ASP.NET MVC
E03 Start A Real Application
Yu Guan | Microsoft MVP
2019-03
AGENDA
 Unit Testing with Visual Studio
 Using Moq
 SportsStore: A Real Application
Unit Testing with Visual Studio
 Creating the Unit Test Project
 Creating the Unit Tests
 Running the Unit Tests
 Implementing the Feature
 Testing and Fixing the Code
Unit Testing with Visual Studio
public interface IDiscountHelper
{
decimal ApplyDiscount(decimal totalParam);
}
public class MinimumDiscountHelper : IDiscountHelper
{
public decimal ApplyDiscount(decimal totalParam)
{
throw new NotImplementedException();
}
}
 If the total is greater than $100, the discount will be 10 percent.
 If the total is between $10 and $100 inclusive, the discount will be $5.
 No discount will be applied on totals less than $10.
 An ArgumentOutOfRangeException will be thrown for negative totals.
Creating the Unit Test Project
 Right-clicking the top-level item in the Solution Explorer and selecting Add ➤
New Project from the pop-up menu.
 You can choose to create a test project when you create a new MVC project:
there is an Add Unit Tests option on the dialog where you choose the initial
content for the project.
Creating the Unit Tests
[TestClass]
public class UnitTest1
{
private IDiscountHelper GetTestObject()
{
return new MinimumDiscountHelper();
}
[TestMethod]
public void Discount_Above_100()
{
// arrange
IDiscountHelper target = GetTestObject();
decimal total = 200;
// act
var discountedTotal = target.ApplyDiscount(total);
// assert
Assert.AreEqual(total * 0.9M, discountedTotal);
}
}
Creating the Unit Tests
Method Description
AreEqual<T>(T, T)
AreEqual<T>(T, T, string)
Asserts that two objects of type T have the same value.
AreNotEqual<T>(T, T)
AreNotEqual<T>(T, T, string)
Asserts that two objects of type T do not have the same value.
AreSame<T>(T, T)
AreSame<T>(T, T, string)
Asserts that two variables refer to the same object.
AreNotSame<T>(T, T)
AreNotSame<T>(T, T, string)
Asserts that two variables refer to different objects.
IsTrue(bool)
IsTrue(bool, string)
Asserts that a bool value is true. Most often used to evaluate
an expression that returns a bool result.
IsFalse(bool)
IsFalse(bool, string)
Asserts that a bool value is false.
Creating the Unit Tests
[TestMethod]
public void Discount_Between_10_And_100()
{
//arrange
IDiscountHelper target = GetTestObject();
// act
decimal TenDollarDiscount = target.ApplyDiscount(10);
decimal HundredDollarDiscount = target.ApplyDiscount(100);
decimal FiftyDollarDiscount = target.ApplyDiscount(50);
// assert
Assert.AreEqual(5, TenDollarDiscount, "$10 discount is wrong");
Assert.AreEqual(95, HundredDollarDiscount, "$100 discount is wrong");
Assert.AreEqual(45, FiftyDollarDiscount, "$50 discount is wrong");
}
[TestMethod]
public void Discount_Less_Than_10()
{
//arrange
IDiscountHelper target = GetTestObject();
// act
decimal discount5 = target.ApplyDiscount(5);
decimal discount0 = target.ApplyDiscount(0);
// assert
Assert.AreEqual(5, discount5);
Assert.AreEqual(0, discount0);
}
[TestMethod]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void Discount_Negative_Total()
{
//arrange
IDiscountHelper target = GetTestObject();
// act
target.ApplyDiscount(-1);
}
Running the Unit Tests
 Visual Studio provides the Test Explorer window for managing and running tests.
Select Windows ➤ Test Explorer from the Visual Studio Test menu to see the
window and click the Run All button near the top-left corner.
Implementing the Feature
public decimal ApplyDiscount(decimal totalParam)
{
if (totalParam < 0)
{
throw new ArgumentOutOfRangeException();
}
else if (totalParam > 100)
{
return totalParam * 0.9M;
}
else if (totalParam > 10 && totalParam <= 100)
{
return totalParam - 5;
}
else
{
return totalParam;
}
}
Testing and Fixing the Code
Using Moq
 Understanding the Problem
 Adding Moq to the Visual Studio Project
 Adding a Mock Object to a Unit Test
 Creating a More Complex Mock Object
Understanding the Problem
public class LinqValueCalculator : IValueCalculator
{
private IDiscountHelper discounter;
private static int counter = 0;
public LinqValueCalculator(IDiscountHelper discountParam)
{
discounter = discountParam;
System.Diagnostics.Debug.WriteLine(
string.Format("Instance {0} created", ++counter));
}
public decimal ValueProducts(IEnumerable<Product> products)
{
return discounter.ApplyDiscount(products.Sum(p => p.Price));
}
}
Understanding the Problem
private Product[] products =
{
new Product {Name = "Kayak", Category = "Watersports", Price = 275M},
new Product {Name = "Lifejacket", Category = "Watersports", Price = 48.95M},
new Product {Name = "Soccer ball", Category = "Soccer", Price = 19.50M},
new Product {Name = "Corner flag", Category = "Soccer", Price = 34.95M}
};
[TestMethod]
public void Sum_Products_Correctly()
{
// arrange
var discounter = new MinimumDiscountHelper();
var target = new LinqValueCalculator(discounter);
var goalTotal = products.Sum(e => e.Price);
// act
var result = target.ValueProducts(products);
// assert
Assert.AreEqual(goalTotal, result);
}
Adding Moq to the Visual Studio Project
 Install-Package Moq -version 4.1.1309.1617 -projectname xxxUnitTests
Adding a Mock Object to a Unit Test
[TestMethod]
public void Sum_Products_Correctly()
{
// arrange
Mock<IDiscountHelper> mock = new Mock<IDiscountHelper>();
mock
.Setup(m => m.ApplyDiscount(It.IsAny<decimal>()))
.Returns<decimal>(total => total);
var target = new LinqValueCalculator(mock.Object);
// act
var result = target.ValueProducts(products);
// assert
Assert.AreEqual(products.Sum(e => e.Price), result);
}
Creating a More Complex Mock Object
[TestMethod]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void Pass_Through_Variable_Discounts()
{
// arrange
Mock<IDiscountHelper> mock = new Mock<IDiscountHelper>();
mock
.Setup(m => m.ApplyDiscount(It.IsAny<decimal>()))
.Returns<decimal>(total => total);
mock
.Setup(m => m.ApplyDiscount(It.Is<decimal>(v => v == 0)))
.Throws<ArgumentOutOfRangeException>();
mock
.Setup(m => m.ApplyDiscount(It.Is<decimal>(v => v > 100)))
.Returns<decimal>(total => (total * 0.9M));
mock
.Setup(m => m.ApplyDiscount(It.IsInRange<decimal>(10, 100, Range.Inclusive)))
.Returns<decimal>(total => total - 5);
var target = new LinqValueCalculator(mock.Object);
// act
decimal FiveDollarDiscount = target.ValueProducts(CreateProduct(5));
decimal TenDollarDiscount = target.ValueProducts(CreateProduct(10));
decimal FiftyDollarDiscount = target.ValueProducts(CreateProduct(50));
decimal HundredDollarDiscount = target.ValueProducts(CreateProduct(100));
decimal FiveHundredDollarDiscount = target.ValueProducts(CreateProduct(500));
// assert
Assert.AreEqual(5, FiveDollarDiscount, "$5 Fail");
Assert.AreEqual(5, TenDollarDiscount, "$10 Fail");
Assert.AreEqual(45, FiftyDollarDiscount, "$50 Fail");
Assert.AreEqual(95, HundredDollarDiscount, "$100 Fail");
Assert.AreEqual(450, FiveHundredDollarDiscount, "$500 Fail");
target.ValueProducts(CreateProduct(0));
}
SportsStore: A Real Application
 Getting Started
 Starting the Domain Model
 Displaying a List of Products
 Preparing a Database
Getting Started
 Creating the Visual Studio Solution and Projects
 Installing the Tool Packages
 Adding References Between Projects
 Setting Up the DI Container
 Running the Application
Creating the Visual Studio Solution and
Projects
 Create a Visual Studio solution that contains three projects. One project will
contain the domain model, one will be the MVC application, and the third will
contain the unit tests. To get started, created a new Visual Studio solution called
SportsStore using the Blank Solution template.
Creating the Visual Studio Solution and
Projects
Project Name Visual Studio Project Template Purpose
Vic.SportsStore.Domain Class Library Holds the domain entities and
logic; set up
for persistence via a repository
created with
the Entity Framework.
Vic.SportsStore.WebApp ASP.NET MVC Web Application (choose
Empty when prompted to choose a project
template and check the MVC option)
Holds the controllers and views;
acts as the
UI for the SportsStore application.
Vic.SportsStore.UnitTests Unit Test Project Holds the unit tests for the other
two projects
Installing the Tool Packages
Install-Package Moq -version 4.1.1309.1617 -projectname Vic.SportsStore.WebApp
Install-Package Moq -version 4.1.1309.1617 -projectname Vic.SportsStore.UnitTests
Install-Package Microsoft.Aspnet.Mvc -version 5.0.0 -projectname Vic.SportsStore.Domain
Install-Package Microsoft.Aspnet.Mvc -version 5.0.0 -projectname Vic.SportsStore.UnitTests
Adding References Between Projects
 Right-click each project in the Solution Explorer window, select Add Reference,
and add the references from the Assemblies ➤ Framework, Assemblies ➤
Extensions or Solution sections.
Project Name Solution Dependencies Assemblies References
Vic.SportsStore.Domain System.ComponentModel.DataAnnotations
Vic.SportsStore.WebApp Vic.SportsStore.Domain
Vic.SportsStore.UnitTests Vic.SportsStore.Domain
Vic.SportsStore.WebApp
System.Web
Microsoft.CSharp
Setting Up the DI Container
Running the Application
Starting the Domain Model
 Add Model
 Creating an Abstract Repository
 Making a Mock Repository
Add Model
 Create a new folder called Entities inside the Vic.SportsStore.Domain project and
then a new C# class file called Product.cs within it
public class Product
{
public int ProductId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public decimal Price { get; set; }
public string Category { get; set; }
}
Creating an Abstract Repository
 Create a new top-level folder inside the Vic.SportsStore.Domain project called
Abstract and, within the new folder, a new interface file called
IProductsRepository.cs You can add a new interface by right-clicking the Abstract
folder, selecting Add ➤ New Item, and selecting the Interface template.
Creating an Abstract Repository
public interface IProductsRepository
{
IEnumerable<Product> Products { get; }
}
Making a Mock Repository
private void AddBindings()
{
Mock<IProductsRepository> mock = new Mock<IProductsRepository>();
mock.Setup(m => m.Products).Returns(new List<Product>
{
new Product { Name = "Football", Price = 25 },
new Product { Name = "Surf board", Price = 179 },
new Product { Name = "Running shoes", Price = 95 }
});
kernel.Bind<IProductsRepository>().ToConstant(mock.Object);
}
Displaying a List of Products
 Adding a Controller
 Adding the Layout, View Start File and View
 Rendering the View Data
 Setting the Default Route
 Running the Application
Adding a Controller
 Right-click the Controllers folder in the Vic.SportsStore.WebApp project and
select Add ➤ Controller from the pop-up menu. Select the MVC 5 Controller –
Empty option, click the Add button and set the name to ProductController. Click
the Add button and Visual Studio will create a new class file called
ProductController.cs
public class ProductController : Controller
{
private IProductsRepository repository;
public ProductController(IProductsRepository productsRepository)
{
this.repository = productsRepository;
}
}
Adding a Controller
 Calling the View method like this (without specifying a view name) tells the
framework to render the default view for the action method. Passing a List of
Product objects to the View method, provides the framework with the data with
which to populate the Model object in a strongly typed view.
public ViewResult List()
{
return View(repository.Products);
}
Adding the Layout, View Start File and View
 Right-click on the List action method in the HomeController class and select Add
View from the pop-up menu. Set View Name to List, set Template to Empty, and
select Product for the Model Class. Ensure that the Use A Layout Page box is
checked and click the Add button to create the view.
Adding the Layout, View Start File and View
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@ViewBag.Title</title>
</head>
<body>
<div>
@RenderBody()
</div>
</body>
</html>
Adding the Layout, View Start File and View
@using Vic.SportsStore.Domain.Entities
@model IEnumerable<Product>
@{
ViewBag.Title = "Products";
}
@foreach (var p in Model)
{
<div>
<h3>@p.Name</h3>
@p.Description
<h4>@p.Price.ToString("c")</h4>
</div>
}
Setting the Default Route
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Product", action = "List", id = UrlParameter.Optional }
);
}
Running the Application
Preparing a Database
 Setup Development Environment for EF Code-First
 Creating the Entity Framework Context
 Adding Data to the Database
 Creating the Product Repository
Creating the Entity Framework Context
Install-Package EntityFramework -projectname Vic.SportsStore.Domain
Install-Package EntityFramework -projectname Vic.SportsStore.WebApp
Creating the Database
 The first step is to create the database connection in Visual Studio. Open the
Server Explorer window from the View menu and click the Connect to Database
button.
Creating the Entity Framework Context
 Create a context class that will associate the model with the database. Create a
new folder in the Vic.SportsStore.Domain project called Concrete and add a new
class file called EFDbContext.cs within it.
public class EFDbContext : DbContext
{
public DbSet<Product> Products { get; set; }
}
Creating the Entity Framework Context
<connectionStrings>
<add name="EFDbContext" connectionString="Data Source=.;Initial Catalog=SportsStore;Persist Security
Info=True;User ID=sa;Password=sa" providerName="System.Data.SqlClient"/>
</connectionStrings>
Creating the Entity Framework Context
 Create a context class that will associate the model with the database. Create a
new folder in the Vic.SportsStore.Domain project called Concrete and add a new
class file called EFDbContext.cs within it.
using (var ctx = new EFDbContext())
{
var product = new Product() { };
ctx.Products.Add(product);
ctx.SaveChanges();
}
Adding Data to the Database
 In the Server Explorer window, expand the Tables item of the SportsStore
database, right-click the Products table, and select Show Table Data.
Creating the Product Repository
 Add a class file to the Concrete folder of the Vic.SportsStore.Domain project
called EFProductRepository.cs
public class EFProductRepository : IProductsRepository
{
private EFDbContext context = new EFDbContext();
public IEnumerable<Product> Products
{
get { return context.Products; }
}
}
Creating the Product Repository
 Edit the NinjectDependencyResolver.cs class file
kernel.Bind<IProductsRepository>().To<EFProductRepository>();
THANK YOU!
Q&A

More Related Content

What's hot

Eclipse Summit Europe '10 - Test UI Aspects of Plug-ins
Eclipse Summit Europe '10 - Test UI Aspects of Plug-insEclipse Summit Europe '10 - Test UI Aspects of Plug-ins
Eclipse Summit Europe '10 - Test UI Aspects of Plug-ins
Tonny Madsen
 
'BIG Testing' with Hans Buwalda
'BIG Testing' with Hans Buwalda 'BIG Testing' with Hans Buwalda
'BIG Testing' with Hans Buwalda
TEST Huddle
 
Spock's New Tricks
Spock's New TricksSpock's New Tricks
Spock's New Tricks
Andres Almiray
 
3 j unit
3 j unit3 j unit
3 j unit
kishoregali
 
Hidden Docs in Angular
Hidden Docs in AngularHidden Docs in Angular
Hidden Docs in Angular
Yadong Xie
 
Selenium my sql and junit user guide
Selenium my sql and junit user guideSelenium my sql and junit user guide
Selenium my sql and junit user guide
Fahad Shiekh
 
Angular Workshop FrOSCon 2018
Angular Workshop  FrOSCon 2018Angular Workshop  FrOSCon 2018
Angular Workshop FrOSCon 2018
Maximilian Berghoff
 
Windows 8 Pure Imagination - 2012-11-25 - Extending Your Game with Windows 8 ...
Windows 8 Pure Imagination - 2012-11-25 - Extending Your Game with Windows 8 ...Windows 8 Pure Imagination - 2012-11-25 - Extending Your Game with Windows 8 ...
Windows 8 Pure Imagination - 2012-11-25 - Extending Your Game with Windows 8 ...
Frédéric Harper
 
Junit
JunitJunit
Junit tutorial
Junit tutorialJunit tutorial
Junit tutorial
Main Uddin Patowary
 
1 aleksandr gritsevski - attd example using
1   aleksandr gritsevski - attd example using1   aleksandr gritsevski - attd example using
1 aleksandr gritsevski - attd example using
Ievgenii Katsan
 
The secret unit testing tools no one ever told you about
The secret unit testing tools no one ever told you aboutThe secret unit testing tools no one ever told you about
The secret unit testing tools no one ever told you about
Dror Helper
 
JUnit Pioneer
JUnit PioneerJUnit Pioneer
JUnit Pioneer
Scott Leberknight
 

What's hot (13)

Eclipse Summit Europe '10 - Test UI Aspects of Plug-ins
Eclipse Summit Europe '10 - Test UI Aspects of Plug-insEclipse Summit Europe '10 - Test UI Aspects of Plug-ins
Eclipse Summit Europe '10 - Test UI Aspects of Plug-ins
 
'BIG Testing' with Hans Buwalda
'BIG Testing' with Hans Buwalda 'BIG Testing' with Hans Buwalda
'BIG Testing' with Hans Buwalda
 
Spock's New Tricks
Spock's New TricksSpock's New Tricks
Spock's New Tricks
 
3 j unit
3 j unit3 j unit
3 j unit
 
Hidden Docs in Angular
Hidden Docs in AngularHidden Docs in Angular
Hidden Docs in Angular
 
Selenium my sql and junit user guide
Selenium my sql and junit user guideSelenium my sql and junit user guide
Selenium my sql and junit user guide
 
Angular Workshop FrOSCon 2018
Angular Workshop  FrOSCon 2018Angular Workshop  FrOSCon 2018
Angular Workshop FrOSCon 2018
 
Windows 8 Pure Imagination - 2012-11-25 - Extending Your Game with Windows 8 ...
Windows 8 Pure Imagination - 2012-11-25 - Extending Your Game with Windows 8 ...Windows 8 Pure Imagination - 2012-11-25 - Extending Your Game with Windows 8 ...
Windows 8 Pure Imagination - 2012-11-25 - Extending Your Game with Windows 8 ...
 
Junit
JunitJunit
Junit
 
Junit tutorial
Junit tutorialJunit tutorial
Junit tutorial
 
1 aleksandr gritsevski - attd example using
1   aleksandr gritsevski - attd example using1   aleksandr gritsevski - attd example using
1 aleksandr gritsevski - attd example using
 
The secret unit testing tools no one ever told you about
The secret unit testing tools no one ever told you aboutThe secret unit testing tools no one ever told you about
The secret unit testing tools no one ever told you about
 
JUnit Pioneer
JUnit PioneerJUnit Pioneer
JUnit Pioneer
 

Similar to Asp netmvc e03

Security Testing
Security TestingSecurity Testing
Security Testing
Kiran Kumar
 
Rhino Mocks
Rhino MocksRhino Mocks
Rhino Mocks
Anand Kumar Rajana
 
Python testing
Python  testingPython  testing
Python testing
John(Qiang) Zhang
 
Opticon 2015 - Getting Started with the Optimizely Developer Platform
Opticon 2015 - Getting Started with the Optimizely Developer PlatformOpticon 2015 - Getting Started with the Optimizely Developer Platform
Opticon 2015 - Getting Started with the Optimizely Developer Platform
Optimizely
 
Unit tests and TDD
Unit tests and TDDUnit tests and TDD
Unit tests and TDD
Roman Okolovich
 
Test driven development
Test driven developmentTest driven development
Test driven development
christoforosnalmpantis
 
Mutation testing Bucharest Tech Week
Mutation testing Bucharest Tech WeekMutation testing Bucharest Tech Week
Mutation testing Bucharest Tech Week
Paco van Beckhoven
 
Building a Pyramid: Symfony Testing Strategies
Building a Pyramid: Symfony Testing StrategiesBuilding a Pyramid: Symfony Testing Strategies
Building a Pyramid: Symfony Testing Strategies
CiaranMcNulty
 
The real beginner's guide to android testing
The real beginner's guide to android testingThe real beginner's guide to android testing
The real beginner's guide to android testing
Eric (Trung Dung) Nguyen
 
Unit Testing in Flutter - From Workflow Essentials to Complex Scenarios
Unit Testing in Flutter - From Workflow Essentials to Complex ScenariosUnit Testing in Flutter - From Workflow Essentials to Complex Scenarios
Unit Testing in Flutter - From Workflow Essentials to Complex Scenarios
Flutter Agency
 
31b - JUnit and Mockito.pdf
31b - JUnit and Mockito.pdf31b - JUnit and Mockito.pdf
31b - JUnit and Mockito.pdf
gauravavam
 
Steps how to create active x using visual studio 2008
Steps how to create active x using visual studio 2008Steps how to create active x using visual studio 2008
Steps how to create active x using visual studio 2008
Yudep Apoi
 
MOPCON 2014 - Best software architecture in app development
MOPCON 2014 - Best software architecture in app developmentMOPCON 2014 - Best software architecture in app development
MOPCON 2014 - Best software architecture in app development
anistar sung
 
Secret unit testing tools no one ever told you about
Secret unit testing tools no one ever told you aboutSecret unit testing tools no one ever told you about
Secret unit testing tools no one ever told you about
Dror Helper
 
Factory method pattern (Virtual Constructor)
Factory method pattern (Virtual Constructor)Factory method pattern (Virtual Constructor)
Factory method pattern (Virtual Constructor)
Sameer Rathoud
 
Qtp 92 Tutorial Anil
Qtp 92 Tutorial AnilQtp 92 Tutorial Anil
Qtp 92 Tutorial Anil
guest3373d3
 
Qtp 92 Tutorial769
Qtp 92 Tutorial769Qtp 92 Tutorial769
Qtp 92 Tutorial769
subhasis100
 
Qtp 9.2 Tutorial
Qtp 9.2 TutorialQtp 9.2 Tutorial
Qtp 9.2 Tutorial
guest37ae7f
 
Qtp 92 Tutorial769
Qtp 92 Tutorial769Qtp 92 Tutorial769
Qtp 92 Tutorial769
subhasis100
 
Qtp 92 Tutorial769
Qtp 92 Tutorial769Qtp 92 Tutorial769
Qtp 92 Tutorial769
vinayaka.nadiger
 

Similar to Asp netmvc e03 (20)

Security Testing
Security TestingSecurity Testing
Security Testing
 
Rhino Mocks
Rhino MocksRhino Mocks
Rhino Mocks
 
Python testing
Python  testingPython  testing
Python testing
 
Opticon 2015 - Getting Started with the Optimizely Developer Platform
Opticon 2015 - Getting Started with the Optimizely Developer PlatformOpticon 2015 - Getting Started with the Optimizely Developer Platform
Opticon 2015 - Getting Started with the Optimizely Developer Platform
 
Unit tests and TDD
Unit tests and TDDUnit tests and TDD
Unit tests and TDD
 
Test driven development
Test driven developmentTest driven development
Test driven development
 
Mutation testing Bucharest Tech Week
Mutation testing Bucharest Tech WeekMutation testing Bucharest Tech Week
Mutation testing Bucharest Tech Week
 
Building a Pyramid: Symfony Testing Strategies
Building a Pyramid: Symfony Testing StrategiesBuilding a Pyramid: Symfony Testing Strategies
Building a Pyramid: Symfony Testing Strategies
 
The real beginner's guide to android testing
The real beginner's guide to android testingThe real beginner's guide to android testing
The real beginner's guide to android testing
 
Unit Testing in Flutter - From Workflow Essentials to Complex Scenarios
Unit Testing in Flutter - From Workflow Essentials to Complex ScenariosUnit Testing in Flutter - From Workflow Essentials to Complex Scenarios
Unit Testing in Flutter - From Workflow Essentials to Complex Scenarios
 
31b - JUnit and Mockito.pdf
31b - JUnit and Mockito.pdf31b - JUnit and Mockito.pdf
31b - JUnit and Mockito.pdf
 
Steps how to create active x using visual studio 2008
Steps how to create active x using visual studio 2008Steps how to create active x using visual studio 2008
Steps how to create active x using visual studio 2008
 
MOPCON 2014 - Best software architecture in app development
MOPCON 2014 - Best software architecture in app developmentMOPCON 2014 - Best software architecture in app development
MOPCON 2014 - Best software architecture in app development
 
Secret unit testing tools no one ever told you about
Secret unit testing tools no one ever told you aboutSecret unit testing tools no one ever told you about
Secret unit testing tools no one ever told you about
 
Factory method pattern (Virtual Constructor)
Factory method pattern (Virtual Constructor)Factory method pattern (Virtual Constructor)
Factory method pattern (Virtual Constructor)
 
Qtp 92 Tutorial Anil
Qtp 92 Tutorial AnilQtp 92 Tutorial Anil
Qtp 92 Tutorial Anil
 
Qtp 92 Tutorial769
Qtp 92 Tutorial769Qtp 92 Tutorial769
Qtp 92 Tutorial769
 
Qtp 9.2 Tutorial
Qtp 9.2 TutorialQtp 9.2 Tutorial
Qtp 9.2 Tutorial
 
Qtp 92 Tutorial769
Qtp 92 Tutorial769Qtp 92 Tutorial769
Qtp 92 Tutorial769
 
Qtp 92 Tutorial769
Qtp 92 Tutorial769Qtp 92 Tutorial769
Qtp 92 Tutorial769
 

More from Yu GUAN

Canada Chinese Microsoft Tech Club Event 1
Canada Chinese Microsoft Tech Club Event 1Canada Chinese Microsoft Tech Club Event 1
Canada Chinese Microsoft Tech Club Event 1
Yu GUAN
 
You can git
You can gitYou can git
You can git
Yu GUAN
 
A Journey to Azure
A Journey to AzureA Journey to Azure
A Journey to Azure
Yu GUAN
 
Dream career dot NET
Dream career dot NETDream career dot NET
Dream career dot NET
Yu GUAN
 
NuGet package CI and CD
NuGet package CI and CDNuGet package CI and CD
NuGet package CI and CD
Yu GUAN
 
Hosting your own NuGet private repository
Hosting your own NuGet private repositoryHosting your own NuGet private repository
Hosting your own NuGet private repository
Yu GUAN
 
Windows service best practice
Windows service best practiceWindows service best practice
Windows service best practice
Yu GUAN
 
Wcf best practice
Wcf best practiceWcf best practice
Wcf best practice
Yu GUAN
 
Unleash the power of code reuse - creating plugins for Xamarin
Unleash the power of code reuse - creating plugins for XamarinUnleash the power of code reuse - creating plugins for Xamarin
Unleash the power of code reuse - creating plugins for Xamarin
Yu GUAN
 
A Journey To Microsoft Azure E00 Azure 101
A Journey To Microsoft Azure E00 Azure 101A Journey To Microsoft Azure E00 Azure 101
A Journey To Microsoft Azure E00 Azure 101
Yu GUAN
 
Welcome to power point
Welcome to power pointWelcome to power point
Welcome to power point
Yu GUAN
 

More from Yu GUAN (11)

Canada Chinese Microsoft Tech Club Event 1
Canada Chinese Microsoft Tech Club Event 1Canada Chinese Microsoft Tech Club Event 1
Canada Chinese Microsoft Tech Club Event 1
 
You can git
You can gitYou can git
You can git
 
A Journey to Azure
A Journey to AzureA Journey to Azure
A Journey to Azure
 
Dream career dot NET
Dream career dot NETDream career dot NET
Dream career dot NET
 
NuGet package CI and CD
NuGet package CI and CDNuGet package CI and CD
NuGet package CI and CD
 
Hosting your own NuGet private repository
Hosting your own NuGet private repositoryHosting your own NuGet private repository
Hosting your own NuGet private repository
 
Windows service best practice
Windows service best practiceWindows service best practice
Windows service best practice
 
Wcf best practice
Wcf best practiceWcf best practice
Wcf best practice
 
Unleash the power of code reuse - creating plugins for Xamarin
Unleash the power of code reuse - creating plugins for XamarinUnleash the power of code reuse - creating plugins for Xamarin
Unleash the power of code reuse - creating plugins for Xamarin
 
A Journey To Microsoft Azure E00 Azure 101
A Journey To Microsoft Azure E00 Azure 101A Journey To Microsoft Azure E00 Azure 101
A Journey To Microsoft Azure E00 Azure 101
 
Welcome to power point
Welcome to power pointWelcome to power point
Welcome to power point
 

Recently uploaded

UI5con 2024 - Keynote: Latest News about UI5 and it’s Ecosystem
UI5con 2024 - Keynote: Latest News about UI5 and it’s EcosystemUI5con 2024 - Keynote: Latest News about UI5 and it’s Ecosystem
UI5con 2024 - Keynote: Latest News about UI5 and it’s Ecosystem
Peter Muessig
 
Measures in SQL (SIGMOD 2024, Santiago, Chile)
Measures in SQL (SIGMOD 2024, Santiago, Chile)Measures in SQL (SIGMOD 2024, Santiago, Chile)
Measures in SQL (SIGMOD 2024, Santiago, Chile)
Julian Hyde
 
Oracle 23c New Features For DBAs and Developers.pptx
Oracle 23c New Features For DBAs and Developers.pptxOracle 23c New Features For DBAs and Developers.pptx
Oracle 23c New Features For DBAs and Developers.pptx
Remote DBA Services
 
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Łukasz Chruściel
 
How Can Hiring A Mobile App Development Company Help Your Business Grow?
How Can Hiring A Mobile App Development Company Help Your Business Grow?How Can Hiring A Mobile App Development Company Help Your Business Grow?
How Can Hiring A Mobile App Development Company Help Your Business Grow?
ToXSL Technologies
 
GreenCode-A-VSCode-Plugin--Dario-Jurisic
GreenCode-A-VSCode-Plugin--Dario-JurisicGreenCode-A-VSCode-Plugin--Dario-Jurisic
GreenCode-A-VSCode-Plugin--Dario-Jurisic
Green Software Development
 
Top Benefits of Using Salesforce Healthcare CRM for Patient Management.pdf
Top Benefits of Using Salesforce Healthcare CRM for Patient Management.pdfTop Benefits of Using Salesforce Healthcare CRM for Patient Management.pdf
Top Benefits of Using Salesforce Healthcare CRM for Patient Management.pdf
VALiNTRY360
 
Using Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional SafetyUsing Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional Safety
Ayan Halder
 
Mobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona InfotechMobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona Infotech
Drona Infotech
 
Empowering Growth with Best Software Development Company in Noida - Deuglo
Empowering Growth with Best Software  Development Company in Noida - DeugloEmpowering Growth with Best Software  Development Company in Noida - Deuglo
Empowering Growth with Best Software Development Company in Noida - Deuglo
Deuglo Infosystem Pvt Ltd
 
Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
Aftab Hussain
 
UI5con 2024 - Bring Your Own Design System
UI5con 2024 - Bring Your Own Design SystemUI5con 2024 - Bring Your Own Design System
UI5con 2024 - Bring Your Own Design System
Peter Muessig
 
Oracle Database 19c New Features for DBAs and Developers.pptx
Oracle Database 19c New Features for DBAs and Developers.pptxOracle Database 19c New Features for DBAs and Developers.pptx
Oracle Database 19c New Features for DBAs and Developers.pptx
Remote DBA Services
 
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit ParisNeo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j
 
Using Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query PerformanceUsing Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query Performance
Grant Fritchey
 
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOMLORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
lorraineandreiamcidl
 
How to write a program in any programming language
How to write a program in any programming languageHow to write a program in any programming language
How to write a program in any programming language
Rakesh Kumar R
 
ALGIT - Assembly Line for Green IT - Numbers, Data, Facts
ALGIT - Assembly Line for Green IT - Numbers, Data, FactsALGIT - Assembly Line for Green IT - Numbers, Data, Facts
ALGIT - Assembly Line for Green IT - Numbers, Data, Facts
Green Software Development
 
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian CompaniesE-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
Quickdice ERP
 
Requirement Traceability in Xen Functional Safety
Requirement Traceability in Xen Functional SafetyRequirement Traceability in Xen Functional Safety
Requirement Traceability in Xen Functional Safety
Ayan Halder
 

Recently uploaded (20)

UI5con 2024 - Keynote: Latest News about UI5 and it’s Ecosystem
UI5con 2024 - Keynote: Latest News about UI5 and it’s EcosystemUI5con 2024 - Keynote: Latest News about UI5 and it’s Ecosystem
UI5con 2024 - Keynote: Latest News about UI5 and it’s Ecosystem
 
Measures in SQL (SIGMOD 2024, Santiago, Chile)
Measures in SQL (SIGMOD 2024, Santiago, Chile)Measures in SQL (SIGMOD 2024, Santiago, Chile)
Measures in SQL (SIGMOD 2024, Santiago, Chile)
 
Oracle 23c New Features For DBAs and Developers.pptx
Oracle 23c New Features For DBAs and Developers.pptxOracle 23c New Features For DBAs and Developers.pptx
Oracle 23c New Features For DBAs and Developers.pptx
 
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
 
How Can Hiring A Mobile App Development Company Help Your Business Grow?
How Can Hiring A Mobile App Development Company Help Your Business Grow?How Can Hiring A Mobile App Development Company Help Your Business Grow?
How Can Hiring A Mobile App Development Company Help Your Business Grow?
 
GreenCode-A-VSCode-Plugin--Dario-Jurisic
GreenCode-A-VSCode-Plugin--Dario-JurisicGreenCode-A-VSCode-Plugin--Dario-Jurisic
GreenCode-A-VSCode-Plugin--Dario-Jurisic
 
Top Benefits of Using Salesforce Healthcare CRM for Patient Management.pdf
Top Benefits of Using Salesforce Healthcare CRM for Patient Management.pdfTop Benefits of Using Salesforce Healthcare CRM for Patient Management.pdf
Top Benefits of Using Salesforce Healthcare CRM for Patient Management.pdf
 
Using Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional SafetyUsing Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional Safety
 
Mobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona InfotechMobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona Infotech
 
Empowering Growth with Best Software Development Company in Noida - Deuglo
Empowering Growth with Best Software  Development Company in Noida - DeugloEmpowering Growth with Best Software  Development Company in Noida - Deuglo
Empowering Growth with Best Software Development Company in Noida - Deuglo
 
Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
 
UI5con 2024 - Bring Your Own Design System
UI5con 2024 - Bring Your Own Design SystemUI5con 2024 - Bring Your Own Design System
UI5con 2024 - Bring Your Own Design System
 
Oracle Database 19c New Features for DBAs and Developers.pptx
Oracle Database 19c New Features for DBAs and Developers.pptxOracle Database 19c New Features for DBAs and Developers.pptx
Oracle Database 19c New Features for DBAs and Developers.pptx
 
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit ParisNeo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
 
Using Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query PerformanceUsing Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query Performance
 
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOMLORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
 
How to write a program in any programming language
How to write a program in any programming languageHow to write a program in any programming language
How to write a program in any programming language
 
ALGIT - Assembly Line for Green IT - Numbers, Data, Facts
ALGIT - Assembly Line for Green IT - Numbers, Data, FactsALGIT - Assembly Line for Green IT - Numbers, Data, Facts
ALGIT - Assembly Line for Green IT - Numbers, Data, Facts
 
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian CompaniesE-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
 
Requirement Traceability in Xen Functional Safety
Requirement Traceability in Xen Functional SafetyRequirement Traceability in Xen Functional Safety
Requirement Traceability in Xen Functional Safety
 

Asp netmvc e03

  • 1. Developing in ASP.NET MVC E03 Start A Real Application Yu Guan | Microsoft MVP 2019-03
  • 2. AGENDA  Unit Testing with Visual Studio  Using Moq  SportsStore: A Real Application
  • 3. Unit Testing with Visual Studio  Creating the Unit Test Project  Creating the Unit Tests  Running the Unit Tests  Implementing the Feature  Testing and Fixing the Code
  • 4. Unit Testing with Visual Studio public interface IDiscountHelper { decimal ApplyDiscount(decimal totalParam); } public class MinimumDiscountHelper : IDiscountHelper { public decimal ApplyDiscount(decimal totalParam) { throw new NotImplementedException(); } }  If the total is greater than $100, the discount will be 10 percent.  If the total is between $10 and $100 inclusive, the discount will be $5.  No discount will be applied on totals less than $10.  An ArgumentOutOfRangeException will be thrown for negative totals.
  • 5. Creating the Unit Test Project  Right-clicking the top-level item in the Solution Explorer and selecting Add ➤ New Project from the pop-up menu.  You can choose to create a test project when you create a new MVC project: there is an Add Unit Tests option on the dialog where you choose the initial content for the project.
  • 6.
  • 7. Creating the Unit Tests [TestClass] public class UnitTest1 { private IDiscountHelper GetTestObject() { return new MinimumDiscountHelper(); } [TestMethod] public void Discount_Above_100() { // arrange IDiscountHelper target = GetTestObject(); decimal total = 200; // act var discountedTotal = target.ApplyDiscount(total); // assert Assert.AreEqual(total * 0.9M, discountedTotal); } }
  • 8. Creating the Unit Tests Method Description AreEqual<T>(T, T) AreEqual<T>(T, T, string) Asserts that two objects of type T have the same value. AreNotEqual<T>(T, T) AreNotEqual<T>(T, T, string) Asserts that two objects of type T do not have the same value. AreSame<T>(T, T) AreSame<T>(T, T, string) Asserts that two variables refer to the same object. AreNotSame<T>(T, T) AreNotSame<T>(T, T, string) Asserts that two variables refer to different objects. IsTrue(bool) IsTrue(bool, string) Asserts that a bool value is true. Most often used to evaluate an expression that returns a bool result. IsFalse(bool) IsFalse(bool, string) Asserts that a bool value is false.
  • 9. Creating the Unit Tests [TestMethod] public void Discount_Between_10_And_100() { //arrange IDiscountHelper target = GetTestObject(); // act decimal TenDollarDiscount = target.ApplyDiscount(10); decimal HundredDollarDiscount = target.ApplyDiscount(100); decimal FiftyDollarDiscount = target.ApplyDiscount(50); // assert Assert.AreEqual(5, TenDollarDiscount, "$10 discount is wrong"); Assert.AreEqual(95, HundredDollarDiscount, "$100 discount is wrong"); Assert.AreEqual(45, FiftyDollarDiscount, "$50 discount is wrong"); } [TestMethod] public void Discount_Less_Than_10() { //arrange IDiscountHelper target = GetTestObject(); // act decimal discount5 = target.ApplyDiscount(5); decimal discount0 = target.ApplyDiscount(0); // assert Assert.AreEqual(5, discount5); Assert.AreEqual(0, discount0); } [TestMethod] [ExpectedException(typeof(ArgumentOutOfRangeException))] public void Discount_Negative_Total() { //arrange IDiscountHelper target = GetTestObject(); // act target.ApplyDiscount(-1); }
  • 10. Running the Unit Tests  Visual Studio provides the Test Explorer window for managing and running tests. Select Windows ➤ Test Explorer from the Visual Studio Test menu to see the window and click the Run All button near the top-left corner.
  • 11. Implementing the Feature public decimal ApplyDiscount(decimal totalParam) { if (totalParam < 0) { throw new ArgumentOutOfRangeException(); } else if (totalParam > 100) { return totalParam * 0.9M; } else if (totalParam > 10 && totalParam <= 100) { return totalParam - 5; } else { return totalParam; } }
  • 12. Testing and Fixing the Code
  • 13. Using Moq  Understanding the Problem  Adding Moq to the Visual Studio Project  Adding a Mock Object to a Unit Test  Creating a More Complex Mock Object
  • 14. Understanding the Problem public class LinqValueCalculator : IValueCalculator { private IDiscountHelper discounter; private static int counter = 0; public LinqValueCalculator(IDiscountHelper discountParam) { discounter = discountParam; System.Diagnostics.Debug.WriteLine( string.Format("Instance {0} created", ++counter)); } public decimal ValueProducts(IEnumerable<Product> products) { return discounter.ApplyDiscount(products.Sum(p => p.Price)); } }
  • 15. Understanding the Problem private Product[] products = { new Product {Name = "Kayak", Category = "Watersports", Price = 275M}, new Product {Name = "Lifejacket", Category = "Watersports", Price = 48.95M}, new Product {Name = "Soccer ball", Category = "Soccer", Price = 19.50M}, new Product {Name = "Corner flag", Category = "Soccer", Price = 34.95M} }; [TestMethod] public void Sum_Products_Correctly() { // arrange var discounter = new MinimumDiscountHelper(); var target = new LinqValueCalculator(discounter); var goalTotal = products.Sum(e => e.Price); // act var result = target.ValueProducts(products); // assert Assert.AreEqual(goalTotal, result); }
  • 16. Adding Moq to the Visual Studio Project  Install-Package Moq -version 4.1.1309.1617 -projectname xxxUnitTests
  • 17. Adding a Mock Object to a Unit Test [TestMethod] public void Sum_Products_Correctly() { // arrange Mock<IDiscountHelper> mock = new Mock<IDiscountHelper>(); mock .Setup(m => m.ApplyDiscount(It.IsAny<decimal>())) .Returns<decimal>(total => total); var target = new LinqValueCalculator(mock.Object); // act var result = target.ValueProducts(products); // assert Assert.AreEqual(products.Sum(e => e.Price), result); }
  • 18. Creating a More Complex Mock Object [TestMethod] [ExpectedException(typeof(ArgumentOutOfRangeException))] public void Pass_Through_Variable_Discounts() { // arrange Mock<IDiscountHelper> mock = new Mock<IDiscountHelper>(); mock .Setup(m => m.ApplyDiscount(It.IsAny<decimal>())) .Returns<decimal>(total => total); mock .Setup(m => m.ApplyDiscount(It.Is<decimal>(v => v == 0))) .Throws<ArgumentOutOfRangeException>(); mock .Setup(m => m.ApplyDiscount(It.Is<decimal>(v => v > 100))) .Returns<decimal>(total => (total * 0.9M)); mock .Setup(m => m.ApplyDiscount(It.IsInRange<decimal>(10, 100, Range.Inclusive))) .Returns<decimal>(total => total - 5); var target = new LinqValueCalculator(mock.Object); // act decimal FiveDollarDiscount = target.ValueProducts(CreateProduct(5)); decimal TenDollarDiscount = target.ValueProducts(CreateProduct(10)); decimal FiftyDollarDiscount = target.ValueProducts(CreateProduct(50)); decimal HundredDollarDiscount = target.ValueProducts(CreateProduct(100)); decimal FiveHundredDollarDiscount = target.ValueProducts(CreateProduct(500)); // assert Assert.AreEqual(5, FiveDollarDiscount, "$5 Fail"); Assert.AreEqual(5, TenDollarDiscount, "$10 Fail"); Assert.AreEqual(45, FiftyDollarDiscount, "$50 Fail"); Assert.AreEqual(95, HundredDollarDiscount, "$100 Fail"); Assert.AreEqual(450, FiveHundredDollarDiscount, "$500 Fail"); target.ValueProducts(CreateProduct(0)); }
  • 19. SportsStore: A Real Application  Getting Started  Starting the Domain Model  Displaying a List of Products  Preparing a Database
  • 20. Getting Started  Creating the Visual Studio Solution and Projects  Installing the Tool Packages  Adding References Between Projects  Setting Up the DI Container  Running the Application
  • 21. Creating the Visual Studio Solution and Projects  Create a Visual Studio solution that contains three projects. One project will contain the domain model, one will be the MVC application, and the third will contain the unit tests. To get started, created a new Visual Studio solution called SportsStore using the Blank Solution template.
  • 22. Creating the Visual Studio Solution and Projects Project Name Visual Studio Project Template Purpose Vic.SportsStore.Domain Class Library Holds the domain entities and logic; set up for persistence via a repository created with the Entity Framework. Vic.SportsStore.WebApp ASP.NET MVC Web Application (choose Empty when prompted to choose a project template and check the MVC option) Holds the controllers and views; acts as the UI for the SportsStore application. Vic.SportsStore.UnitTests Unit Test Project Holds the unit tests for the other two projects
  • 23.
  • 24.
  • 25. Installing the Tool Packages Install-Package Moq -version 4.1.1309.1617 -projectname Vic.SportsStore.WebApp Install-Package Moq -version 4.1.1309.1617 -projectname Vic.SportsStore.UnitTests Install-Package Microsoft.Aspnet.Mvc -version 5.0.0 -projectname Vic.SportsStore.Domain Install-Package Microsoft.Aspnet.Mvc -version 5.0.0 -projectname Vic.SportsStore.UnitTests
  • 26. Adding References Between Projects  Right-click each project in the Solution Explorer window, select Add Reference, and add the references from the Assemblies ➤ Framework, Assemblies ➤ Extensions or Solution sections. Project Name Solution Dependencies Assemblies References Vic.SportsStore.Domain System.ComponentModel.DataAnnotations Vic.SportsStore.WebApp Vic.SportsStore.Domain Vic.SportsStore.UnitTests Vic.SportsStore.Domain Vic.SportsStore.WebApp System.Web Microsoft.CSharp
  • 27. Setting Up the DI Container
  • 29. Starting the Domain Model  Add Model  Creating an Abstract Repository  Making a Mock Repository
  • 30. Add Model  Create a new folder called Entities inside the Vic.SportsStore.Domain project and then a new C# class file called Product.cs within it public class Product { public int ProductId { get; set; } public string Name { get; set; } public string Description { get; set; } public decimal Price { get; set; } public string Category { get; set; } }
  • 31. Creating an Abstract Repository  Create a new top-level folder inside the Vic.SportsStore.Domain project called Abstract and, within the new folder, a new interface file called IProductsRepository.cs You can add a new interface by right-clicking the Abstract folder, selecting Add ➤ New Item, and selecting the Interface template.
  • 32. Creating an Abstract Repository public interface IProductsRepository { IEnumerable<Product> Products { get; } }
  • 33. Making a Mock Repository private void AddBindings() { Mock<IProductsRepository> mock = new Mock<IProductsRepository>(); mock.Setup(m => m.Products).Returns(new List<Product> { new Product { Name = "Football", Price = 25 }, new Product { Name = "Surf board", Price = 179 }, new Product { Name = "Running shoes", Price = 95 } }); kernel.Bind<IProductsRepository>().ToConstant(mock.Object); }
  • 34. Displaying a List of Products  Adding a Controller  Adding the Layout, View Start File and View  Rendering the View Data  Setting the Default Route  Running the Application
  • 35. Adding a Controller  Right-click the Controllers folder in the Vic.SportsStore.WebApp project and select Add ➤ Controller from the pop-up menu. Select the MVC 5 Controller – Empty option, click the Add button and set the name to ProductController. Click the Add button and Visual Studio will create a new class file called ProductController.cs public class ProductController : Controller { private IProductsRepository repository; public ProductController(IProductsRepository productsRepository) { this.repository = productsRepository; } }
  • 36. Adding a Controller  Calling the View method like this (without specifying a view name) tells the framework to render the default view for the action method. Passing a List of Product objects to the View method, provides the framework with the data with which to populate the Model object in a strongly typed view. public ViewResult List() { return View(repository.Products); }
  • 37. Adding the Layout, View Start File and View  Right-click on the List action method in the HomeController class and select Add View from the pop-up menu. Set View Name to List, set Template to Empty, and select Product for the Model Class. Ensure that the Use A Layout Page box is checked and click the Add button to create the view.
  • 38. Adding the Layout, View Start File and View <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>@ViewBag.Title</title> </head> <body> <div> @RenderBody() </div> </body> </html>
  • 39. Adding the Layout, View Start File and View @using Vic.SportsStore.Domain.Entities @model IEnumerable<Product> @{ ViewBag.Title = "Products"; } @foreach (var p in Model) { <div> <h3>@p.Name</h3> @p.Description <h4>@p.Price.ToString("c")</h4> </div> }
  • 40. Setting the Default Route public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Product", action = "List", id = UrlParameter.Optional } ); }
  • 42. Preparing a Database  Setup Development Environment for EF Code-First  Creating the Entity Framework Context  Adding Data to the Database  Creating the Product Repository
  • 43. Creating the Entity Framework Context Install-Package EntityFramework -projectname Vic.SportsStore.Domain Install-Package EntityFramework -projectname Vic.SportsStore.WebApp
  • 44. Creating the Database  The first step is to create the database connection in Visual Studio. Open the Server Explorer window from the View menu and click the Connect to Database button.
  • 45. Creating the Entity Framework Context  Create a context class that will associate the model with the database. Create a new folder in the Vic.SportsStore.Domain project called Concrete and add a new class file called EFDbContext.cs within it. public class EFDbContext : DbContext { public DbSet<Product> Products { get; set; } }
  • 46. Creating the Entity Framework Context <connectionStrings> <add name="EFDbContext" connectionString="Data Source=.;Initial Catalog=SportsStore;Persist Security Info=True;User ID=sa;Password=sa" providerName="System.Data.SqlClient"/> </connectionStrings>
  • 47. Creating the Entity Framework Context  Create a context class that will associate the model with the database. Create a new folder in the Vic.SportsStore.Domain project called Concrete and add a new class file called EFDbContext.cs within it. using (var ctx = new EFDbContext()) { var product = new Product() { }; ctx.Products.Add(product); ctx.SaveChanges(); }
  • 48. Adding Data to the Database  In the Server Explorer window, expand the Tables item of the SportsStore database, right-click the Products table, and select Show Table Data.
  • 49. Creating the Product Repository  Add a class file to the Concrete folder of the Vic.SportsStore.Domain project called EFProductRepository.cs public class EFProductRepository : IProductsRepository { private EFDbContext context = new EFDbContext(); public IEnumerable<Product> Products { get { return context.Products; } } }
  • 50. Creating the Product Repository  Edit the NinjectDependencyResolver.cs class file kernel.Bind<IProductsRepository>().To<EFProductRepository>();