30 ĐỀ PHÁT TRIỂN THEO CẤU TRÚC ĐỀ MINH HỌA BGD NGÀY 22-3-2024 KỲ THI TỐT NGHI...
Mock object
1. Unit test và NUnit
SỬ DỤNG MOCK OBJECT
TRONG UNIT TESTING
Trình bày: Nhóm 13, 14, 15
1 Le Van Long – FIT – HCMUS 4/10/2011
2. NỘI DUNG
Mock object là gì?
Phân loại mock object.
Lợi ích của mock object.
Cách sử dụng mock object.
2 Le Van Long – FIT – HCMUS 4/10/2011
3. NỘI DUNG
Mock object là gì?
Phân loại mock object.
Lợi ích của mock object.
Cách sử dụng mock object.
3 Le Van Long – FIT – HCMUS 4/10/2011
4. ĐỊNH NGHĨA
A mock object is simply a testing replacement for a real-
world object.
Andy Hunt, David Thomas – Pragmatic unit testing in C#
with NUnit, 2nd edition, p91.
Mock Objects are a technique that allow you to isolate
classes from their dependencies for testing purposes.
Geoff Lane
4 Le Van Long – FIT – HCMUS 4/10/2011
5. NỘI DUNG
Mock object là gì?
Phân loại mock object.
Lợi ích của mock object.
Cách sử dụng mock object.
5 Le Van Long – FIT – HCMUS 4/10/2011
6. PHÂN LOẠI
• Static mock: đƣợc viết bằng tay hay phát sinh tự động
ở một bƣớc nào đó trong chƣơng trình.
• Dynamic mock: phụ thuộc vào proxy interface.
6 Le Van Long – FIT – HCMUS 4/10/2011
7. NỘI DUNG
Mock object là gì?
Phân loại mock object.
Lợi ích của mock object.
Cách sử dụng mock object.
7 Le Van Long – FIT – HCMUS 4/10/2011
8. LỢI ÍCH
Mock object đƣợc sử dụng trong các trƣờng hợp sau:
Đối tƣợng thật có những hành vi không đoán biết
đƣợc. Ví dụ: tỉ giá trên thị trƣờng chứng khoán.
Đối tƣợng thật khó cài đặt. Ví dụ: môi trƣờng mạng.
Đối tƣợng thật chậm.
8 Le Van Long – FIT – HCMUS 4/10/2011
9. LỢI ÍCH (tt)
Đối tƣợng thật có/là giao diện ngƣời dùng.
Việc kiểm chứng cần biết một đối tƣợng thật đƣợc sử
dụng nhƣ thế nào? Ví dụ, việc kiểm chứng cần biết một
hàm callback có đƣợc gọi hay không?
Đối tƣợng thật không tồn tại.
9 Le Van Long – FIT – HCMUS 4/10/2011
10. NỘI DUNG
Mock object là gì?
Phân loại mock object.
Lợi ích của mock object.
Cách sử dụng mock object.
10 Le Van Long – FIT – HCMUS 4/10/2011
11. CÁCH SỬ DỤNG MOCK OBJECT
Stubs
Fakes
Mock objects
11 Le Van Long – FIT – HCMUS 4/10/2011
12. CÁCH SỬ DỤNG MOCK OBJECT
Stubs
Fakes
Mock objects
12 Le Van Long – FIT – HCMUS 4/10/2011
13. STUB
Bƣớc 1: Sử dụng interfaces để mô tả những phƣơng
thức của đối tƣợng.
Bƣớc 2: Cài đặt interface cho production code.
Bƣớc 3: Cài đặt interface cho mock object.
13 Le Van Long – FIT – HCMUS 4/10/2011
14. STUBS
INTERFACE
REAL STUB
CLASS CLASS
TESTED
FUNCTION
14 Le Van Long – FIT – HCMUS 4/10/2011
15. STUB-VÍ DỤ (1)
Có một lớp truy xuất CSDL:
public class RealDAO
{
public string GetName(long id)
{
// Do something
}
}
15 Le Van Long – FIT – HCMUS 4/10/2011
16. STUB-VÍ DỤ (2)
Từ những phƣơng thức cần giả lập, rút ra interface.
public interface DAO
{
string GetName(long id);
}
16 Le Van Long – FIT – HCMUS 4/10/2011
17. STUB-VÍ DỤ (3)
Áp dụng interface này cho lớp mình muốn giả lập (cho
lớp này kế thừa interface).
public class RealDAO : DAO
{
public string GetName(long id)
{
// Do something
}
17
} Le Van Long – FIT – HCMUS 4/10/2011
18. STUB-VÍ DỤ (4)
Cho lớp stub kế thừa từ interface này. Cho phƣơng
thức trả về một giá trị giả mà chúng ta nghĩ chƣơng
trình sẽ trả ra.
public class StubDAO : DAO
{
public string GetName(long id)
{
return "XDPM";
}
} Le Van Long – FIT – HCMUS
18 4/10/2011
19. STUB-VÍ DỤ (5)
Dùng stub object để test các chức năng liên quan:
public class PrintBill
{
public static string Print(string name)
{
string result;
if (name == "XDPM")
{
result = "Xin dung phun em";
}
else
{
result = "Unknown";
}
return result;
}
19 } Le Van Long – FIT – HCMUS 4/10/2011
20. STUB-VÍ DỤ (6)
[TestFixture]
public class PrintTest
{
Test]
public void XDPMTest()
{
StubDAO stub = new StubDAO();
string actualValue =
PrintBill.Print(stub.GetName(0));
Assert.That(actualValue, Is.EqualTo("Xay dung phan
mem"));
}
}
20 Le Van Long – FIT – HCMUS 4/10/2011
21. CÁCH SỬ DỤNG MOCK OBJECT
Stubs
Fakes
Mock objects
21 Le Van Long – FIT – HCMUS 4/10/2011
22. VẤN ĐỀ
Đôi khi chúng ta cần làm nhiều thứ hơn là chỉ trả về một
giá trị (nhƣ trên) để có thể test đƣợc đoạn code chúng
ta viết.
Ví dụ:
Có một file do chúng ta tạo ra tuân theo một format nào
đó.
Có một lớp đọc dữ liệu từ file này và cần kiểm tra xem
việc đọc file đƣợc thực hiện đúng hay không:
22 Le Van Long – FIT – HCMUS 4/10/2011
23. FAKE-VÍ DỤ (1)
public class PhanTachFile
{
private FileStream _stream;
public PhanTachFile(string fileName)
{
_stream = File.Open(fileName,
FileMode.Open);
}
// Do something
}
23 Le Van Long – FIT – HCMUS 4/10/2011
24. NHẬN XÉT
Để test đƣợc các phƣơng thức của lớp này cần một
file thật từ ổ đĩa. Điều này vừa không cần thiết, vừa làm
chậm tốc độ test.
Giải pháp:
24 Le Van Long – FIT – HCMUS 4/10/2011
25. FAKE-VÍ DỤ (2)
private FileStream _stream;
public PhanTachFile(string fileName)
{
#if TESTING
_stream = new MemoryStream();
//MemoryStream là một lớp trong .NET cho phép tạo
ra một stream bên trong bộ nhớ chính.
#else
_stream = File.Open(fileName, FileMode.Open);
#endif
}
25 Le Van Long – FIT – HCMUS 4/10/2011
26. FAKE LÀ GÌ?
•Fake là một đối tƣợng giả lập các đối tƣợng thật.
•Fake có phần cài đặt của nó (ví dụ nhƣ phần cài đặt
của lớp MemoryStream trong ví dụ bên trên).
•Fakes không đƣợc sử dụng cho mục đích tạo ra sản
phẩm, nó chủ yếu giúp cho việc test đƣợc thực hiện
nhanh hơn.
•Ví dụ: MemoryStream, SQLite (một dạng in-memory
database)…
26 Le Van Long – FIT – HCMUS 4/10/2011
27. CÁCH SỬ DỤNG MOCK OBJECT
Stubs
Fakes
Mock objects
27 Le Van Long – FIT – HCMUS 4/10/2011
28. MOCK OBJECT LÀ GÌ?
•Mock object là một đối tƣợng cụ thể hóa một interface
nào đó, trả về giá trị chúng ta muốn nó trả về và
kiểm tra xem nó có hoạt động theo cách mà chúng
ta mong muốn hay không.
28 Le Van Long – FIT – HCMUS 4/10/2011
29. CÁCH SỬ DỤNG MOCK
OBJECTS TRONG NUNIT
•Bƣớc 1: Add reference đến thƣ viện nunit.mocks.dll
nằm trong thƣ mục cài đặt (..binnet 2.0framework).
•Bƣớc 2: Using NUnit.Mocks trong chƣơng trình.
•Bƣớc 3: Viết code sử dụng mock object. Lƣu ý khởi tạo
các expectation cho mock object.
29 Le Van Long – FIT – HCMUS 4/10/2011
30. MOCK-VÍ DỤ (1)
Trở lại ví dụ về lớp DAO ở phần Stub, chúng ta sẽ test
phƣơng thức PrintBill bằng cách sử dụng một mock
object thay cho lớp DAO thật nhƣ sau:
30 Le Van Long – FIT – HCMUS 4/10/2011
31. MOCK-VÍ DỤ (2)
using NUnit.Mocks;
[Test]
public void XDPMTest_UsingMock()
{
DynamicMock mockController = new DynamicMock(typeof(DAO));
DAO mockDAO = mockController.MockInstance as DAO;
// Set up expectation
mockController.ExpectAndReturn("GetName", // Tên phương thức
string.Empty,// Giá trị trả về
0); // Đối số mong
muốn, là null nếu muốn phương thức nhận bất kì đối số nào
// Exercise test
string actualValue = PrintBill.Print(mockDAO.GetName(1));
mockController.Verify(); // Kiểm tra các expections có được
thực hiện hay không?
Assert.That(actualValue, Is.EqualTo("Xay dung phan mem"));
31 } Le Van Long – FIT – HCMUS 4/10/2011
32. MOCK-VÍ DỤ (3) – KẾT QUẢ
32 Le Van Long – FIT – HCMUS 4/10/2011
33. NHẬN XÉT
•Test fail không phải do kết quả trả về của phƣơng thức
Print sai mà do giá trị truyền vào phƣơng thức
GetName không đúng với expectation (Expected: 0, But
was: 1).
• Ngoài việc kiểm tra đƣợc trạng thái (state verification),
tức là giá trị các biến trƣớc và sau khi thực hiện hàm
giống nhƣ stub, mock object còn kiểm tra đƣợc hành vi
(behavior verification) hay tƣơng tác (interaction
verification), tức là cách thức mà các phƣơng thức
đƣợc gọi thực hiện. => Đây là điểm khác biệt lớn nhất
giữa stub và mock.
33 Le Van Long – FIT – HCMUS 4/10/2011
34. MỘT SỐ PHƢƠNG THỨC
KHÁC CỦA LỚP DynamicMock
Tên phương thức Công dụng
ExpectNoCall(string methodName) Mong muốn phƣơng thức methodName
không đƣợc gọi. Nếu phƣơng thức này
đƣợc gọi, test sẽ fail.
ExpectAndThrow(string Giống ExpectAndReturn. Thay vì trả về 1 giá
methodName, Exception trị, throw ra một Exception để kiểm tra hệ
exception, param sobject[] args) thống xử lý Exception có hoạt động tốt hay
không.
SetReturnValue(string Thiết đặt cho phƣơng thức methodName
methodName, object returnValue) luôn luôn trả về một giá trị.
34 Le Van Long – FIT – HCMUS 4/10/2011
35. TÓM TẮT
Đặc tính Fake Stub Mock
Cách Thay thế những đối Cụ thể hóa 1 interface, Cụ thể hóa 1 interface nhƣng
thực hiện tƣợng thật bằng cho các phƣơng thức chỉ ra các phƣơng thức nào
những đối tƣợng có trả về các giá trị cố muốn hoặc không muốn đƣợc
chức năng tƣơng định. thực hiện, cách thức thực hiện,
đƣơng. giá trị trả về (nếu có) và đối số
mong muốn (nếu có). (Dynamic
mock)
Mục đích Thay thế cho các đối tƣợng thật.
Giúp cho việc test Kiểm soát đầu vào của Kiểm tra đầu ra của SUT (giá trị
đƣợc thực hiện nhanh thành phần đƣợc test trả về, cách thức gọi thực hiện
hơn hoặc giả lập các (System Under Test – phƣơng thức…)
đối tƣợng không có SUT). Bắt buộc SUT
thật. phải đi theo con đƣờng
mà chúng ta muốn.
Phân loại Static mock Dynamic mock
Loại kiểm Kiểm tra trạng thái (tình trạng các biến Kiểm tra trạng thái và hành vi
tra trƣớc/sau khi thực hiện phƣơng thức). (cách thức các phƣơng thức
đƣợc gọi thực hiện)
35 Le Van Long – FIT – HCMUS 4/10/2011
36. THAM KHẢO
• Andrew Hunt, David Thomas with Mart Hargett, “Pragmatic Unit
Testing in C# with NUnit”, 2nd edition, 2007.
• Martin Fowler, “Mocks Aren’t Stubs”, last update 02/01/2007,
http://martinfowler.com/articles/mocksArentStubs.html
• Gerard Meszaros, “Mocks, Fakes, Stubs and Dummies”, last
update 24/07/2008,
http://xunitpatterns.com/Mocks,%20Fakes,%20Stubs%20and%2
0Dummies.html
• Diadora Alexandru, “Difference between Mocks and Stubs”, last
update 21/04/2009,
http://geekswithblogs.net/diadiora/archive/2009/04/21/difference-
between-mocks-and-stubs.aspx
36 Le Van Long – FIT – HCMUS 4/10/2011
Editor's Notes
Đây là 2 khái niệm khó hiểu. Sau khi xem hết slide, các bạn sẽ hiểu được nó.
Tạm sử dụng khái niệm stub class/stub object để chỉ lớp/đối tượng kế thừa từ một interface theo phương pháp Stub.Về mặt ngữ nghĩa, stub có nghĩa là gốc.
Hiện tại chúng ta chưa có CSDL hoặc phương thức GetName viết chưa xong + việc truy xuất ổ đĩa chậm.
MemoryStream là một lớp trong .NET cho phép tạo ra một stream bên trong bộ nhớ chính.Đoạn code trên cần phải design lại để có thể test tốt hơn. Chi tiết xem tại tài liệu tham khảo.
Lưu ý: khái niệm mock object ban đầu là khái niệm chung, cơ bản. Ở đây sẽ giới thiệu cụ thể về mock object cùng với framework của nó, cụ thể ở đây là mock framework của NUnit.Trong lập trình hướng đối tượng của C#, khái niệm interface gần giống với khái niệm lớp cha thuần ảo của C++.