استفاده از shim و stub برای mock کردن در آزمون واحد
نویسنده: آرش خوشبخت
تاریخ: ۱۳۹۲/۰۱/۲۸ ۲۲:۵۰
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
namespace FakingExample
{
public class CartToShim
{
public int CartId { get; private set; }
public int UserId { get; private set; }
private List<CartItem> _cartItems = new List<CartItem>();
public ReadOnlyCollection<CartItem> CartItems { get; private set; }
public DateTime CreateDateTime { get; private set; }
public CartToShim(int cartId, int userId)
{
CartId = cartId;
UserId = userId;
CreateDateTime = DateTime.Now;
CartItems = new ReadOnlyCollection<CartItem>(_cartItems);
}
public void AddCartItem(int productId)
{
var cartItemId = DataAccessLayer.SaveCartItem(CartId, productId);
_cartItems.Add(new CartItem(cartItemId, productId));
}
}
}public class CartItem
{
public int CartItemId { get; private set; }
public int ProductId { get; private set; }
public CartItem(int cartItemId, int productId)
{
CartItemId = cartItemId;
ProductId = productId;
}
}ShimDataAccessLayer را که مشاهده میکنید یک متد SaveCartItem دارد که به دیتابیس متصل شده و آیتمهای کارت را ذخیره میکند.
حالا میتوانیم تست خود را بنویسیم. در زیر یک نمونه از تست را مشاهده میکنید:
[TestMethod]
public void AddCartItem_GivenCartAndProduct_ThenProductShouldBeAddedToCart()
{
//Create a context to scope and cleanup shims
using (ShimsContext.Create())
{
int cartItemId = 42, cartId = 1, userId = 33, productId = 777;
//Shim SaveCartItem rerouting it to a delegate which
//always returns cartItemId
Fakes.ShimDataAccessLayer.SaveCartItemInt32Int32 = (c, p) => cartItemId;
var cart = new CartToShim(cartId, userId);
cart.AddCartItem(productId);
Assert.AreEqual(cartId, cart.CartItems.Count);
var cartItem = cart.CartItems[0];
Assert.AreEqual(cartItemId, cartItem.CartItemId);
Assert.AreEqual(productId, cartItem.ProductId);
}
}به این نکته توجه داشته باشید که حتما برای assert کردن باید assertها را در داخل اسکوپ ShimsContext قرار گرفته باشد در غیر این صورت assert شما درست کار نمیکند.
این یک مثال از shim بود؛ حالا میخواهم مثالی از یک stub را برای شما بزنم. یک اینترفیس با نام ICartSaver به صورت زیر ایجاد کنید:
public interface ICartSaver
{
int SaveCartItem(int cartId, int productId);
}public class CartSaver : ICartSaver
{
public int SaveCartItem(int cartId, int productId)
{
using (var conn = new SqlConnection("RandomSqlConnectionString"))
{
var cmd = new SqlCommand("InsCartItem", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@CartId", cartId);
cmd.Parameters.AddWithValue("@ProductId", productId);
conn.Open();
return (int)cmd.ExecuteScalar();
}
}
}[TestMethod]
public void AddCartItem_GivenCartAndProduct_ThenProductShouldBeAddedToCart()
{
int cartItemId = 42, cartId = 1, userId = 33, productId = 777;
//Stub ICartSaver and customize the behavior via a
//delegate, ro return cartItemId
var cartSaver = new Fakes.StubICartSaver();
cartSaver.SaveCartItemInt32Int32 = (c, p) => cartItemId;
var cart = new CartToStub(cartId, userId, cartSaver);
cart.AddCartItem(productId);
Assert.AreEqual(cartId, cart.CartItems.Count);
var cartItem = cart.CartItems[0];
Assert.AreEqual(cartItemId, cartItem.CartItemId);
Assert.AreEqual(productId, cartItem.ProductId);
}سلام
(نوع stub همانند فریم ورک mock میباشد )
تعریفی که از stup تو راهنماش اومده با مطلبی که شما ذکر کردید متفاوته
Martin Fowler’s article Mocks aren’t Stubs compares and contrasts the underlying principles of Stubs and Mocks. As outlined in Martin Fowler’s article, a stub provides static canned state which results in state verification of the system under test, whereas a mock provides a behavior verification of the results for the system under test and their indirect outputs as related to any other component dependencies while under test