Exercise 3: Testing Cart Actions

In this exercise, you will learn how to test the main functionality of the ShoppingCartController: adding items to the cart, removing items and displaying the cart’s content. In order to simulate those actions, the tests you will implement will use a TestCartIdProvider instance that will return a new Guid object to simulate the ID of the cart to handle for the test. The MvcMusicStore project, the one used for the application itself, behaves differently: another provider works with the user’s session to store and retrieve the cart ID.

Task 1 – Running ShoppingCartController Tests

In this task you will run the 3 tests you will be implementing later during this Exercise. Since they are not implemented with the correct content yet, they will fail.

  1. Start Microsoft Visual Studio 2010 Professional from Start | All Programs | Microsoft Visual Studio 2010 | Microsoft Visual Studio 2010.
  2. In the File menu, choose Open Project. In the Open Project dialog, browse to Source\Ex03-Testing Cart actions\Begin, select MvcMusicStore.sln and click Open.
  3. In the Solution Explorer expand the MvcMusicStore.Tests project and double-click the ShoppingCartControllerTest.[cs|vb] class to open that file.
  4. You will find 3 test methods included as part of the Begin solution of this exercise: IndexTest, AddToCartTest and RemoveFromCartTest. Run all tests in the solution to verify that those 3 are failing. To do this, click on the following button in the Test toolbar or press CTRL+R, A.

    Figure 1

    Running all tests in the solution

  5. The 3 test methods mentioned run and fail.

    Figure 2

    Tests failing

Task 2 – Implementing the test for the AddToCart action method

In this task you will implement the test for the AddToCart action method of the ShoppingCart Controller. The AddToCart method receives an album ID that is used to retrieve the album from the database, add it to the shopping cart and then returns the Index View template that will display that album as part of the cart.

  1. Open the ShoppingCartControllerTest.[cs|vb] file and replace the using directives with the following, needed to run the tests of this Exercise:

    (Code Snippet – ASP.NET MVC 3.0 Testing – Ex3 using directives – CSharp)

    C#

    using MvcMusicStore.Controllers; using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using System.Linq; using Microsoft.VisualStudio.TestTools.UnitTesting.Web; using System.Web.Mvc; using MvcMusicStore.Models; using System.Collections.Generic; using System.Transactions; using MvcMusicStore.ViewModels;

    (Code Snippet – ASP.NET MVC 3.0 Testing – Ex3 using directives – VB)

    Visual Basic

    Imports MvcMusicStore.Controllers Imports Microsoft.VisualStudio.TestTools.UnitTesting Imports System Imports System.Linq Imports Microsoft.VisualStudio.TestTools.UnitTesting.Web Imports System.Web.Mvc Imports MvcMusicStore.Models Imports System.Collections.Generic Imports System.Transactions Imports MvcMusicStore.ViewModels

  2. Replace the AddToCartTest method. Note that the Assert.Inconclusive method was removed with the real implementation for the test.

    (Code Snippet – ASP.NET MVC 3.0 Testing – Ex3 AddToCartTest – CSharp)

    C#

    /// <summary>
    FakePre-efbb433410214538912d2fc77065652f-d7e350fea61f48c1b207f83a8c2c0f04FakePre-1c15b78d3f1e4442a57e1f39c1429e51-81d3f76bf291403aacd5ce405f58f199FakePre-42c3e0357098425a977342efc66858d7-0e87eb4732384ebd9719456564ae1d49FakePre-4f6cffa1fcfe4276bc8f07452b0593bb-f244b35f3f7e4258ae58fc1212a51997FakePre-5630ec1e3b9d4a4eaac67cbe909487ab-6121d10496374682a4a07c9b269eb683FakePre-03aede10ecaf40e9afc433a5e8ea4d79-596a23ce3c364edca95c4ed7899ab6efFakePre-1b0e3810f550435c9ae43d971964de05-86627963f8914349991603facaf21848 using (TransactionScope ts = new TransactionScope()) { ICartIdProvider provider = new TestCartIdProvider(); ShoppingCartController target = new ShoppingCartController(provider); int id = 669; ActionResult actual; actual = target.AddToCart(id); Assert.IsNotNull(actual); ShoppingCart cart = ShoppingCart.GetCart(provider); List<Cart> items = cart.GetCartItems(); Assert.IsNotNull(items); Assert.AreEqual(1, items.Count); Assert.AreEqual(id, items[0].AlbumId); Assert.AreEqual(1, items[0].Count); }FakePre-bc6f389800764877a101beabbf11092e-98305156287041c1b10f41d1088dfd57FakePre-adf3ebf5ca894962850ab2f987ff8512-5932285067d142f88c6823fa7aa9d8b7FakePre-da29af8ce3294c06acceb881aea45ce0-0cb8963f654247d4a57c38a6671aba1bFakePre-ef38c4da6ba540e696db9e8322ef1ca1-ccd52a6f41264f8e84f3c12dd690aadaFakePre-8f89968772854957ace8fb0d5cce4fee-006cba5d863544239853e7ed6da7af63

    (Code Snippet – ASP.NET MVC 3.0 Testing – Ex3 AddToCartTest – VB)

    Visual Basic

    ''' <summary>
    FakePre-956fe9a51747469181157455e66ba850-68ac6272e0394614b2a3738c008a1a31FakePre-91ad69da1b074a998f15cbf40e0727ec-f6ff68ae83104aa6b75ef370e8950deeFakePre-f0e37f403d9f4b2fbf15017ed45d74d5-72fbcf6e6e1f42aba82daa330e3314d8FakePre-6abfb17550204f48b54ef04db4c7e009-526e3e1e8f4e4d0ea77d12cb15c8c8d4using (TransactionScope ts = New TransactionScope()) Dim provider As ICartIdProvider = New TestCartIdProvider() Dim target As New ShoppingCartController(provider) Dim id As Integer = 669 Dim actual As ActionResult actual = target.AddToCart(id) Assert.IsNotNull(actual) Dim cart As ShoppingCart = ShoppingCart.GetCart(provider) Dim items As List(Of Cart) = cart.GetCartItems() Assert.IsNotNull(items) Assert.AreEqual(1, items.Count) Assert.AreEqual(id, items(0).AlbumId) Assert.AreEqual(1, items(0).Count)FakePre-e9a5226ebb8943d9add90c3224e705ca-8b50fe902d2d4ee6887ca4a4737b4fe3FakePre-b7e9c417ded846f686fbc80c245d9bec-ae5e4414ec2448ec81df33068c3dc62aFakePre-51f3b47af8d142f59b4447c23eac0b7d-63a840894e22472a923ecc9e1511c305FakePre-223e49779d21468fb0e073892e8a478e-ab6722480daa42279b3ba18552189a47FakePre-b22d51b88ce04c2eb2b28010f1078fb6-0e6859b3adef45c59807717449877e59

    Note:
    In order to simulate the addition of an album to the shopping cart, this test will need to invoke the ShoppingCartController’s AddToCart action. You will find that when creating the ShoppingCartController object, a TestCartIdProvider instance is passed as parameter.

    TestCartIdProvider implements ICartIdProvider and will return a new Guid object to simulate the ID of the cart where you will add a new album. In the MvcMusicStore project, the one used for the application itself, the provider used is the CartIdProvider, which also implements ICartIdProvider but instead uses the user’s session to store and retrieve the cart ID. So, if you run the web application, its default behavior is to use the session id provider, as in previous exercise.

    Once the ShoppingCartController object is created, a well-known album id (669) is used to invoke the AddToCart action. Afterwards, the cart items are retrieved and the test asserts that:

    1. Result of AddToCart invocation is not null

    2. The cart’s items list is not null

    3. There is only one cart

    4. The cart’s first item’s ID is the same used on the AddtoCart action

    5. The cart contains only one item (the album recently added)

  3. Run exclusively this test to verify the results. To do this, right-click inside the AddToCartTest method and then select Run Tests.
  4. The Test Result window should show that the test passes.

    Figure 3

    Running test AddToCartTest

Task 3 – Implementing the test for the Index action method

In this task you will implement the test for the Index action method of the ShoppingCart Controller. The Index method populates a ShoppingCartViewModel object with the cart items and its total cost in order to display them with the corresponding View template.

  1. In the ShoppingCartControllerTest.[cs|vb] file, add the GetAlbum private method, needed to test the Index action method.

    (Code Snippet – ASP.NET MVC 3.0 Testing – Ex3 GetAlbum method – CSharp)

    C#

    private Album GetAlbum(int id) { MusicStoreEntities storeDB = new MusicStoreEntities(); return storeDB.Albums.Single(a => a.AlbumId == id); }

    (Code Snippet – ASP.NET MVC 3.0 Testing – Ex3 GetAlbum method – VB)

    Visual Basic

    Private Function GetAlbum(ByVal id As Integer) As Album Dim storeDB As New MusicStoreEntities() Return storeDB.Albums.Single(Function(a) a.AlbumId = id) End Function

  2. Replace the IndexTest method. Note that the Assert.Inconclusive method was removed with the real implementation for the test.

    (Code Snippet – ASP.NET MVC 3.0 Testing – Ex3 IndexTest – CSharp)

    C#

    /// <summary>
    FakePre-ae97a202b8c64cb4999f8c28f2f28047-18deac468d5a4393a003df9260730facFakePre-53cf385d8b8d4fb29cebda56c73c4841-15585e56de3e441c9db851d6f5a3b644FakePre-1aacc1dec96840bba141a41b19725a3e-3d5374cd8a004a9a88e9b7d81cb98fcbFakePre-eae1a38184ba4257a5e0e9c040d2b41e-cbb53e7d04b84dbbbef2d27d314336f3FakePre-d3e710733bbd4bd0b18d123086560613-866ba0f717274393b19de79335010732FakePre-8bc377879f534046ae46d37462a23553-69aafdd465004b429d20f6bc4e7f486cFakePre-9d0608d5a37b474fb323b7a94c3122a3-44c0fd42e6444cff9ac4f4c230488650 using (TransactionScope ts = new TransactionScope()) { Album album1 = this.GetAlbum(669); Album album2 = this.GetAlbum(668); ICartIdProvider provider = new TestCartIdProvider(); ShoppingCart cart = ShoppingCart.GetCart(provider); cart.AddToCart(album1); cart.AddToCart(album2); cart.AddToCart(album2); ShoppingCartController target = new ShoppingCartController(provider); ActionResult actual; actual = target.Index(); Assert.IsNotNull(actual); Assert.IsInstanceOfType(actual, typeof(ViewResult)); ViewResult viewResult = (ViewResult)actual; Assert.IsInstanceOfType(viewResult.ViewData.Model, typeof(ShoppingCartViewModel)); ShoppingCartViewModel model = (ShoppingCartViewModel)viewResult.ViewData.Model; Assert.AreEqual(2, model.CartItems.Count); Assert.AreEqual(3, model.CartItems.Sum(it => it.Count)); }FakePre-15dd1079601e45bdb3a4b622abc6312f-217a989cee694770937d1c4f5da2f2e3FakePre-a5deac46b10d4359867328c5f12c732f-92174d9a567a44a5b0754f855398e4b7FakePre-21d3a76022ee427895c1826e2eb3556e-3358048f62f249b7ba2176f5ef1163a5FakePre-404c3157adbd42fd9be541af16ace93b-e4b583cfde8a4248809e9a5e0dae2bcbFakePre-df94b0c4ddaa46e7b5f99f16883297a4-1c41b911a22e4ec484fb8bcab2ce9534FakePre-735ea5063ef041ceaee3564d048a99df-fb6dd0bc867c4410857438e58220442eFakePre-bf5dab040eb54c78a2cb647bd57cea3a-d8403ea7280b44cca8f10b23f27e3c7dFakePre-6f74f84454d14daab4c89ddccbc3f8b7-7d0d9c30bf124bc7a73bddf3e7159ae3FakePre-d7a548e737544fbd90c2625b7406bb29-84ec8fec385041aabb03cb28fb1a1169

    (Code Snippet – ASP.NET MVC 3.0 Testing – Ex3 IndexTest – VB)

    Visual Basic

    ''' <summary>
    FakePre-8e2d8921299e4196ac9fd72f9ceea08a-e6a31b2ff0214096a04e326142c03e76FakePre-5fac60ce59254af482f593d09a538662-df8cd34e2f0146da93a66d5af5ec81d9FakePre-81fc7cf5b4a94d54b18da4e35bfa5bcb-dccc0026c3ee48e28e8292da80a44b46FakePre-133f4029bf8a4708af0e415fc95c8dd2-6f838b125ead4158adb78a6ba8c376ba using (TransactionScope ts = New TransactionScope()) Dim album1 As Album = Me.GetAlbum(669) Dim album2 As Album = Me.GetAlbum(668) Dim provider As ICartIdProvider = New TestCartIdProvider() Dim cart As ShoppingCart = ShoppingCart.GetCart(provider) cart.AddToCart(album1) cart.AddToCart(album2) cart.AddToCart(album2) Dim target As New ShoppingCartController(provider) Dim actual As ActionResult actual = target.Index() Assert.IsNotNull(actual) Assert.IsInstanceOfType(actual, GetType(ViewResult)) Dim viewResult As ViewResult = CType(actual, ViewResult) Assert.IsInstanceOfType(viewResult.ViewData.Model, GetType(ShoppingCartViewModel)) Dim model As ShoppingCartViewModel = CType(viewResult.ViewData.Model, ShoppingCartViewModel) Assert.AreEqual(2, model.CartItems.Count) Assert.AreEqual(3, model.CartItems.Sum(Function(it) it.Count))FakePre-826664d546cc449d865d29bd87f66814-0ca115d691ed42bc8a52cdc0ea3717a1FakePre-dc06c39396094e289309a825d5c08272-b63d72ff7c674eb68b7ecc7939032d15FakePre-2d13daa802f7407389394d656b2d7022-7ca30d5b50f946f8ad6b33ba477571f2FakePre-892776d0139e4299b3837b425f1ffbdb-79516087fade4cdea05f97bff2e5dc8dFakePre-ac0b0651a51b406a9506e059b3d2b581-001151ec1bab4f22baac7e08437d9026FakePre-f0da779783664a14ac01f4871de36f13-48670be5008e40c7b3b3fa66762b0e64FakePre-03f8f2dd3ef446b98770d2a1ff8d79b7-065b63052ac24aa09d29437669fa4850FakePre-12882589bc704d698c03f6eff213297f-87d5cc998f16477795be34d5f2b39b0dFakePre-e8a61969b5d94258991b3a980ea143d3-42e929f841844ed99facc67ad8a43fb2

    Note:
    In order to simulate the correct display of the shopping cart content, this test will:

    1. Retrieve from the database 2 well-known albums

    2. Add them to a new shopping cart: the first album once and the second album twice; hence making the cart to hold 3 items.

    3. Invoke the Index action method of the ShoppingCartController.

    4. Assert that:

    - Result of that invocation is not null

    - Result of that invocation is actually a View

    - The view’s model is of type ShoppingCartViewModel

    - The view’s model holds 2 cart items which are different

    - The view’s model holds 3 cart items in total

  3. Run exclusively this test to verify the results. To do this, right-click inside the IndexTest method and then select Run Tests.
  4. The Test Result window should show that the test passes.

    Figure 4

    Running test IndexTest

Task 4 – Implementing the test for the RemoveFromCart action method

In this task you will implement the test for the RemoveFromCart action method of the ShoppingCart Controller. The RemoveFromCart receives the ID of the album to remove, used for invoking the RemoveFromCart method of the ShoppingCart Model class and then it displays a confirmation message.

  1. In the ShoppingCartControllerTest.[cs|vb] file, replace the RemoveFromCartTest method. Note that the Assert.Inconclusive method was removed with the real implementation for the test.

    (Code Snippet – ASP.NET MVC 3.0 Testing – Ex3 RemoveFromCartTest – CSharp)

    C#

    /// <summary>
    FakePre-fba857af2f6041b48b42c01b49ec2aac-99e068a535c54d438ade30aed12def8bFakePre-16ef411f2ed54d2faf743877d9064ee4-4c0630e7d047455493a4397a1eb954ddFakePre-cba322c9ddfd460c92bd4e8426fccbb0-82ca0c08c8f047d0935d7bb1322113eaFakePre-62c03ff73cd340aeb5d89977ebccf3c9-46817752df16495997365a1ce090fd40FakePre-93beac4014534980bf70c728209664e6-87ed6281fe984e13be9d7ba33f352805FakePre-0e784ca583844fc89eee43229e54f0f9-2eb6f3e602b04afda6a32d60c8f22228FakePre-21967ebccbae4898bbbd7723479390e8-6d129de87f47475f9e510947f33d4c2d using (TransactionScope ts = new TransactionScope()) { Album album1 = this.GetAlbum(669); Album album2 = this.GetAlbum(668); ICartIdProvider provider = new TestCartIdProvider(); ShoppingCart cart = ShoppingCart.GetCart(provider); cart.AddToCart(album1); cart.AddToCart(album2); cart.AddToCart(album2); ShoppingCartController target = new ShoppingCartController(provider); int id = cart.GetCartItems().First().RecordId; ActionResult actual; actual = target.RemoveFromCart(id); Assert.IsNotNull(actual); Assert.IsInstanceOfType(actual, typeof(JsonResult)); JsonResult jsonResult = (JsonResult)actual; Assert.IsInstanceOfType(jsonResult.Data, typeof(ShoppingCartRemoveViewModel)); ShoppingCartRemoveViewModel model = (ShoppingCartRemoveViewModel)jsonResult.Data; Assert.AreEqual(2, model.CartCount); Assert.AreEqual(id, model.DeleteId); }FakePre-cd25cd0682f34e149a935080486d8333-7df71e1bb3494f449a7500b95a592086FakePre-78017b9c3f434b0598a1bfd2bb7fa31a-7b38feb5246c48bfb91122a3cae32c66FakePre-33fbe927da0941c185e5bbe01a4f0eac-2cfe94673cff4aa5ae22430c5b2626beFakePre-eddd08c3827e4bb5beaa1be3a8c29bd3-cf827ed33d014ca0862d77fe76689b79FakePre-affa90799dba4138a92ba37c27e4f64b-359582caa9c445e786cfb8c0023c6d32FakePre-1163f9b056944b3ab142e4b2c3479d21-7b8d052b7f4b4e5f94754c4d55dd4d81FakePre-e919ad7802884163b3b3713013977566-7900195abda344aba8db1495176b2539FakePre-193a9778f3c24e14b46decbd49367164-7839802da977429ca1f5c1e4a86a53f4FakePre-777de5b1b9f74fec8ea8c9b68b9c8031-5c89dcea08774bd48ed1b3c4b11ba333

    (Code Snippet – ASP.NET MVC 3.0 Testing – Ex3 RemoveFromCartTest – VB)

    Visual Basic

    ''' <summary>
    FakePre-954e541094514397b559b39da9827615-eb558acc55a246c1a70089d3af650ac5FakePre-050e0d762413492db7d6c200607d0652-d89692c7cd2a46938ed5dfbea1edc992FakePre-9c3585ac43f0468da33b338f899d4b3e-70080d9e5792431db6af9d8a38667d93FakePre-689a58a5c27e4a0fae5862a5e0a08e2d-5e4d8181b0cb44ab98f447c48d9a1ea8 using (TransactionScope ts = New TransactionScope()) Dim album1 As Album = Me.GetAlbum(669) Dim album2 As Album = Me.GetAlbum(668) Dim provider As ICartIdProvider = New TestCartIdProvider() Dim cart As ShoppingCart = ShoppingCart.GetCart(provider) cart.AddToCart(album1) cart.AddToCart(album2) cart.AddToCart(album2) Dim target As New ShoppingCartController(provider) Dim id As Integer = cart.GetCartItems().First().RecordId Dim actual As ActionResult actual = target.RemoveFromCart(id) Assert.IsNotNull(actual) Assert.IsInstanceOfType(actual, GetType(JsonResult)) Dim jsonResult As JsonResult = CType(actual, JsonResult) Assert.IsInstanceOfType(jsonResult.Data, GetType(ShoppingCartRemoveViewModel)) Dim model As ShoppingCartRemoveViewModel = CType(jsonResult.Data, ShoppingCartRemoveViewModel) Assert.AreEqual(2, model.CartCount) Assert.AreEqual(id, model.DeleteId)FakePre-0f4b61d7c13c425ca12ee19731f07d33-b474232532fe4f1dab6a587804af2f40FakePre-4d8f5e56191b4fc9b3c13d28dbaa33e3-3ef705d4ef294115899d9f6e3323f0d0FakePre-35bc5a06e41243adb85f277dae6562fb-640b8b0b15604c359c1bf93af30495d6FakePre-36ac73646be24fc8863f108cc9af2431-df4110f1fafb4fcb9e4b4e1e6726d9d4FakePre-a120a7433e464966adbfe6a9b3bddcaf-9eca4b4202d643628837b7c55dc1c443FakePre-f2c4530779ff4e40b49325cbbe5f5632-557786eb4de44366b63d51261cf3b322FakePre-e64ccfe69f9d4d638f81080b054324e8-d01065473ae04e3c85391c5261bba84cFakePre-9ec22a43a361463a8997b8485a28ae89-f11bc7e8330a448090cf3ad6501a37f1FakePre-421d241c94ce4c798d066f6da7620784-368389395235408caad9c9e1052e1da9

    Note:
    In order to simulate the correct removal of an album from the shopping cart, this test will:

    1. Retrieve from the database 2 well-known albums

    2. Add them to a new shopping cart: the first album once and the second album twice; hence making the cart to hold 3 items.

    3. Retrieve the ID of the first album added to the cart

    4. Invoke the RemoveFromCart action method of the ShoppingCartController, passing the ID retrieved in the last step.

    5. Assert that:

    - Result of that invocation is not null

    - Result of that invocation is actually Json

    - Json’s result data is of type ShoppingCartRemoveViewModel

    - Json’s result data now holds 2 cart items in total (instead of 3)

    - Json’s result data’s ID of the removed item matches the ID of the first album added to the cart, which was removed from the cart later.

  2. Run exclusively this test to verify the results. To do this, right-click inside the RemoveFromCartTest method and then select Run Tests.
  3. The Test Result window should show that the test passes.

    Figure 5

    Running test RemoveFromCartTest

Next Step

Summary