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测试失败。

 

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