Thứ Bảy, 22 tháng 11, 2014

Test-Driven Development (TDD) trong .NET – Phần 3

Phần này sẽ cài đặt các Test 3 và Test 4 trong loại bài về Test-Driven Development trong .NET qua ví dụ. Các phần trước bao gồm:

Test 3: Push một đối tượng đơn, Pop đối tượng đó và xác nhận IsEmptylà true.


Trong Test case này, ta thêm một phương thức mới cho lớp Stack có nhiệm vụ lấy ra phần tử trên đỉnh của Stack. Nhưng trước tiên, ta cần tiến thành cài đặt unit test cho test case này, đoạn code như sau:
    [Test]
    public void Pop()
    {
        stack.Push("first element");
        stack.Pop();
        Assert.IsTrue(stack.IsEmpty,
            "Sau khi Push - Pop. IsEmpty phải bằng true.");
    }
Và tất nhiên, ta phải cài đặt một phương thức Pop trong lớp Stack.
    public void Pop()
    {
    }
Tuy nhiên, nếu bây giờ bạn tiến hành complite và chạy test, thì sẽ trả về kết quả fail. Do đó, ta bổ sung thêm m_IsEmpty = true để hoàn thành test case này.
    public void Pop()
    {
        m_IsEmpty = true;
    }
Kết quả là chúng ta đã hoàn thành unit test cho Test case 3. Tiếp theo, ta sẽ cài đặt test case 4.

Test 4: Push một đối tượng đơn, ghi nhớ đối tượng đó; Pop đối tượng, và xác nhận hai đối tượng này là giống nhau.

Trong unit test của test case này, chúng ta sẽ thực hiện so sánh nội dung của 2 phần tử, đó là phần từ đưa vào Stack với phần tử lấy ra từ Stack ngay sau khi đưa vào. Do đó, ta sẽ đặt tên là PushPopContentCheck:
    [Test]
    public void PushPopContentCheck()
    {
        int expected = 1234;
        stack.Push(expected);   
        int actual = (int) stack.Pop();
        Assert.AreEqual(expected, actual);
    }
Tiếp theo, ta cần phải thay đổi lại phương thức Pop của lớp Stack.
    public object Pop()
    {
        m_IsEmpty = true;
        return null;
    }
Sau khi build thành công và chạy test, thì kết quả test trả về sẽ error vì lúc này ta chưa trả về giá trị trên đỉnh của Stack. Do đó, để pass cho unit test này, chúng ta lưu lại giá trị nhận được từ Push và trả lại giá trị trong Pop. Đoạn code sau khi thay đổi sẽ như sau:
using System;

public class Stack
{
    private bool m_IsEmpty = true;
    private object m_Element;

    public bool IsEmpty
    {
        get {
            return m_IsEmpty;
        }
    }

    public void Push(object element)
    {
        m_IsEmpty = false;
        m_Element = element;
    }

    public object Pop()
    {
        m_IsEmpty = true;
        object top = m_Element;
        m_Element = null;
        return top;
    }
}
Lúc này, ta thấy phương thức IsEmpty chỉ cần kiểm tra xem phần tử đang được lưu có bằng null hay không. Do đó, ta sẽ thay đổi ở phương thức IsEmpty như sau:
using System;

public class Stack
{
    private object m_Element = null;

    public bool IsEmpty
    {
        get {
            return (m_Element == null);
        }
    }

    public void Push(object element)
    {
        m_Element = element;
    }

    public object Pop()
    {
        object top = m_Element;
        m_Element = null;
        return top;
    }
}
Lúc này đã tốt hơn với code của Stack vì ta thấy rằng lúc này chỉ cần cập nhập lại một biến thay vì hai như trước đây.  Đến lúc này, khi thực hiện đưa vào 1 phần tử thì nó vẫn nằm trên đỉnh của Stack vì lúc lấy ra ta lấy đúng phần tử đã đưa vào. Tuy nhiên, sẽ có vấn đề lúc đưa nhiều hơn 1 phần từ vào Stack, ta sẽ được thấy điều này qua các test case tiếp theo.

Không có nhận xét nào: