0

I am a bit confused about how to correctly mock an object. From what I have seen in the example on NSubstitute, this is the basic setup for an assert. My understanding is this is about testing the behavior of the method. My questions are as follows:

  1. Is this the correct way to mock getting a host name of a device.

    [TestMethod]
    public void MockedDeviceHostName()
    {
        //Arrange 
        var device = Substitute.For<IDeviceLogic>();
        Device mockedDevice = new Device();     
    
        //Act   
        device.GetHostName("IP Address","Object Identifier Repository","CommunityString").Returns(mockedDevice.hostName);
    
        //Assert
        Assert.AreEqual(mockedDevice.hostName, device.GetHostName("IP Address", "Object Identifier Repository", "CommunityString"));
    
    }
    
  2. What is the advantage of mocking. I of course understand this is behavior based testing, I mean in terms that I am setting the behavior expectations so I feel they will always be correct even if there is an error with the method, in this case. I am looking for a bit of clarity on mocking vs Unit Tests and integration tests.

Nkosi
  • 235,767
  • 35
  • 427
  • 472
Mdukes00
  • 131
  • 1
  • 1
  • 8

1 Answers1

0

Mocking is generally used for replacing a dependency of a class/object, so that its logic can be tested in isolation from that dependency.

In your example there isn't really a class relying on the mocked IDeviceLogic. A closer example might be something like a form that needs to display information about a device. In that case, it would be nice to run basic tests of the form logic without attaching a real device.

[Test]
public void SetDeviceNameOnLoad() {
    //Arrange 
    var device = Substitute.For<IDeviceLogic>();
    var view = Substitute.For<IDeviceView>();
    var form = new DevicePresenter(device, deviceView);
    device.GetHostName("IP Address","Object Identifier Repository","CommunityString").Returns("sample device name");

    //Act   
    form.Load();

    //Assert
    Assert.AreEqual("sample device name", view.DeviceName);
}

One advantage of this is we can isolate some logic we want to test from transient conditions (e.g. device could be disconnected, network could be down etc.). We can also simulate conditions that could be difficult to reliably automated test (e.g. we simulate a web service returning a specific HTTP status code). And we can make tests faster (e.g. a device could take 30 seconds to connect -- we can mock this out to simulate it connecting immediately).

The disadvantage is that we are only simulating dependencies -- if the real thing acts differently our test is worse than useless. For example, if you have to call device.Connect() on the real device before the host name becomes available, then your mock will not share this behaviour without additional work.

Hope this helps.

David Tchepak
  • 9,826
  • 2
  • 56
  • 68