Moq

To add Moq to your unit test project, right-click on your test project and choose Manage NuGet Packages. Browse for Moq, and choose to install the latest stable version. We won't delve too deeply into Moq, but we will show how mocking frameworks help facilitate testing the boundaries of your application.

Add a test to verify that the Search method of the SpeakerService is called once from the Search action result of the controller:

[Fact]
public void ItCallsSearchServiceOnce()
{
// Arrange
// Act
_controller.Search("jos");

// Assert
_speakerServiceMock.Verify(mock => mock.Search(It.IsAny<string>()),
Times.Once());
}

In order to make the test pass, you will also be required to do a little more setup in the constructor of the test class:

private readonly SpeakerController _controller;
private static Mock<ISpeakerService> _speakerServiceMock;

public SpeakerControllerSearchTests()
{
var speaker = new Speaker
{
Name = "test"
};

// define the mock
_speakerServiceMock = new Mock<ISpeakerService>();

// when search is called, return list of speakers containing speaker
_speakerServiceMock.Setup(x => x.Search(It.IsAny<string>()))
.Returns(() => new List<Speaker> { speaker });

// pass mock object as ISpeakerService
_controller = new SpeakerController(_speakerServiceMock.Object);
}

Be sure to modify the interface so that the application will compile:

public interface ISpeakerService
{
IEnumerable<Speaker> Search(string searchString);
}

Now, make your test pass by ensuring the Search method of the SpeakerService is called from the Search action result of the controller. If you haven't done so already, create a field variable for _speakerService that is assigned in the constructor by the speakerService parameter:

private readonly ISpeakerService _speakerService;

public SpeakerController(ISpeakerService speakerService)
{
_speakerService = speakerService;
}

[Route("search")]
public IActionResult Search(string searchString)
{
var hardCodedSpeakers = new List<Speaker>
{
new Speaker{Name = "Josh"},
new Speaker{Name = "Joshua"},
new Speaker{Name = "Joseph"},
new Speaker{Name = "Bill"},
};

_speakerService.Search("foo");

var speakers = hardCodedSpeakers.Where(x =>
x.Name.StartsWith(searchString,
StringComparison.OrdinalIgnoreCase)).ToList();

return Ok(speakers);
}

Next, add a test to validate that the searchString supplied to the Search action result of the controller is the searchString being passed to the Search method of the SpeakerService:

[Fact]
public void GivenSearchStringThenSpeakerServiceSearchCalledWithString(){
// Arrange
var searchString = "jos";

// Act
_controller.Search(searchString);

// Assert
_speakerServiceMock.Verify(mock => mock.Search(searchString),
Times.Once());
}

And make the test pass by supplying searchString to the Search method on the ­_speakerService:

  _speakerService.Search(searchString);

Now, ensure that the results of the Search method from the SpeakerService are what is being returned by the action result:

[Fact]
public void GivenSpeakerServiceThenResultsReturned()
{
// Arrange
var searchString = "jos";

// Act
var result = _controller.Search(searchString) as OkObjectResult;

// Assert
Assert.NotNull(result);
var speakers = ((IEnumerable<Speaker>)result.Value).ToList();
Assert.Equal(_speakers, speakers);
}

Remember, the results returned by the Search method of the SpeakerService are being defined by the Mock. You'll need to extract a field in order to test that the results being returned by the action result are the same as those being defined for our Mock:

private readonly SpeakerController _controller;
private static Mock<ISpeakerService> _speakerServiceMock;
private readonly List<Speaker> _speakers;

public SpeakerControllerSearchTests()
{
_speakers = new List<Speaker> { new Speaker
{
Name = "test"
} };

_speakerServiceMock = new Mock<ISpeakerService>();
_speakerServiceMock.Setup(x => x.Search(It.IsAny<string>()))
.Returns(() => _speakers);

_controller = new SpeakerController(_speakerServiceMock.Object);
}

There's still the problem of the hard-coded data. Don't forget to remove unnecessary and unneeded code while you're making your test pass. Remember red, green, refactor. This applies to your production code as well as your tests.

You may encounter some failing tests once you remove the hard-coded data. For now, skip these tests, as we'll be moving this logic to another part of the application. Now it's time to create a SpeakerService:

xUnit
[Fact(Skip="Reason for skipping")]
MSTest
[Skip]
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.224.59.192