stub will not make test fail, but mock will.

stub will not make test fail, but mock will. 

In the context of unit testing, stubs and mocks are both used to isolate the code under test from external dependencies. However, they serve different purposes and have different behaviors.

Stub: A stub is a simple implementation of an interface or a class that returns predefined values. It is used to provide indirect input to the code under test. Stubs do not have any expectations on how they should be called, so they will not cause a test to fail if the code under test calls them differently than expected.

Mock: A mock, on the other hand, is an object that records how it was called and can be set up with expectations on how it should be called. If the code under test does not call the mock as expected, the test will fail. Mocks are used to verify the interaction between the code under test and its dependencies.

Here's an example to illustrate the difference:

Suppose you have an interface IDataService with a method GetData():

public interface IDataService
{
    string GetData();
}

And you have a class MyClass that depends on IDataService:  被測試類是MyClass,被測試方法是ProcessData

public class MyClass
{
    private readonly IDataService _dataService;

    public MyClass(IDataService dataService)
    {
        _dataService = dataService;
    }

    public string ProcessData()
    {
        string data = _dataService.GetData();
        // Do something with the data and return the result
    }
}

Now, let's create a stub and a mock for IDataService:

// Stub
public class DataServiceStub : IDataService
{
    public string GetData()
    {
        return "stub data";
    }
}

// Mock
public class DataServiceMock : IDataService
{
    public int GetDataCallCount { get; private set; }

    public string GetData()
    {
        GetDataCallCount++;
        return "mock data";
    }
}

In your unit test, you can use the stub to provide input to MyClass without any expectations:

[Test]
public void TestWithStub()
{
    IDataService dataServiceStub = new DataServiceStub();
    MyClass myClass = new MyClass(dataServiceStub);

    string result = myClass.ProcessData();

    // Assert the result based on the input provided by the stub
}

However, if you want to verify that MyClass calls GetData() exactly once,you can use the mock:

[Test]
public void TestWithMock()
{
    IDataService dataServiceMock = new DataServiceMock();
    MyClass myClass = new MyClass(dataServiceMock);

    string result = myClass.ProcessData();

    // Assert the result based on the input provided by the mock
    // Verify that GetData() was called exactly once
    Assert.AreEqual(1, (dataServiceMock as DataServiceMock).GetDataCallCount);
}

In this example, if MyClass does not call GetData() exactly once, the test with the mock will fail, while the test with the stub will not.

In summary, stubs are used to provide indirect input to the code under test without any expectations, while mocks are used to verify the interaction between the code under test and its dependencies. If the code under test does not meet the expectations set on the mock, the test will fail.

 

上面的stub測試,不需要驗證行爲。因爲MyClass中的ProcessData方法調用了IDataService的GetData方法多少次,是沒關係的。調用一次或者兩次,甚至更多次,都不會導致測試失敗。

而Mock測試,需要驗證IDataService的GetData方法被調用次數,如果調用次數超過的話,就會導致Mock測試失敗。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章