IEnumerable interface TDD using Mock in C# [duplicate] - c#

This question already has answers here:
Testing a function that returns IEnumerable<string>
(2 answers)
Closed 4 years ago.
Below is the FizzBuzz Generation Code,
public class BusinessHandler : IBusinessHandler
{
private readonly IEnumerable<IBusinessRule> BusinessRule;
public BusinessHandler(IEnumerable<IBusinessRule> businessrule)
{
this.BusinessRule = businessrule;
}
public IEnumerable<string> GetResult(int inputValue)
{
var outputList = new List<string>();
for (int element = 1; element <= inputValue; element++)
{
string tempOutput = element.ToString();
var divisionResult = this.BusinessRule.FirstOrDefault(x => x.IsDivisible(element));
if (divisionResult != null)
{
tempOutput = divisionResult.PrintOutput();
}
outputList.Add(tempOutput);
}
return outputList;
}
}
Here IBusinessHandler, IBusinessRule are the interface. Using Dependency Injection, i am calling this method in my web application.
IBusinessRule :
public interface IBusinessRule
{
bool IsDivisible(int inputValue);
string PrintOutput();
}
3 classes are implementing IBusinessRule interface.
I am new to TDD, how can I implement unit test for GetResult() method.
For TDD i am using Nunit,Moq packages.

A test for the provided code can look like this
[TestClass]
public class BusinessHandlerTests {
[TestMethod]
public void BusinessHandler_Should_GetResult() {
//Arrange
var fizz = new Mock<IBusinessRule>();
fizz.Setup(_ => _.IsDivisible(It.IsAny<int>()))
.Returns((int value) => value % 3 == 0);
fizz.Setup(_ => _.PrintOutput()).Returns("Fizz");
var buzz = new Mock<IBusinessRule>();
buzz.Setup(_ => _.IsDivisible(It.IsAny<int>()))
.Returns((int value) => value % 5 == 0);
buzz.Setup(_ => _.PrintOutput()).Returns("Buzz");
var fizzbuzz = new Mock<IBusinessRule>();
fizzbuzz.Setup(_ => _.IsDivisible(It.IsAny<int>()))
.Returns((int value) => value % 15 == 0);
fizzbuzz.Setup(_ => _.PrintOutput()).Returns("FizzBuzz");
var businessRule = new[] {
fizzbuzz.Object, fizz.Object, buzz.Object // <--order is important
};
var subject = new BusinessHandler(businessRule);
var inputValue = 15;
var expected = new[] { "1", "2", "Fizz", "4", "Buzz", "Fizz", "7", "8", "Fizz", "Buzz", "11", "Fizz", "13", "14", "FizzBuzz" };
//Act
var actual = subject.GetResult(inputValue);
//Assert
actual.Should().BeEquivalentTo(expected);
}
}
Assuming the business rules have not already been defined, they can be mocked and injected into the subject under test, as demonstrated above.
If for example the classes already existed
public class FizzObject : IBusinessRule {
public bool IsDivisible(int inputValue) => inputValue % 3 == 0;
public string PrintOutput() => "Fizz";
}
then they can be initialized
var businessRule = new[] { new FizzBuzzObject(), new FizzObject(), new BuzzObject() }; // <--order is important
and injected into the subject under test with the same expected behavior

You don't need mocks for testing "FizzBuzz".
As you said you have 3 implementations of IBusinessRule
public class RuleOne : IBusinessRule { ... }
public class RuleTwo : IBusinessRule { ... }
public class RuleThree : IBusinessRule { ... }
Then you can write test which cover whole logic. With this kind of test you will test BusinessHandler and all implementations of IBusinessRule will be tested as well.
With this test you will have freedom to redesign how BusinessHandler implemented (possibly need to change only constructor)
// Here used NUnit feature of TestCase to provide values to the test function
[Test]
[TestCase(1, new[] { "1" })]
[TestCase(3, new[] { "Fizz" })]
[TestCase(5, new[] { "Buzz" })]
[TestCase(15, new[] { "Fizz", "Buzz" })]
[TestCase(20, new[] { "20" })]
public void ShouldReturnExpectedResult(int input, string[] expected)
{
// Arrange
var rules = new[]
{
new RuleOne();
new RuleTwo();
new RuleThree();
}
var handler = new BusinessHandler(rules);
// Act
var actual = handler.GetResult(input);
// Assert
actual.Should().BeEquivalent(expected);
}

Related

New virtual creates a new method instead of hiding

The requirement here is to write test cases for the Opc Ua NodeManager and it uses NodeId from Opc.Ua class.
Methods/properties in NodeId class cannot be moq because they are Non-Overridable methods and have ony get in them.
So I created a wrapper on top of NodeId class and tried to Moq that class. It works fine but now I have 2 methods/Properties
public class NodeIdTestClass : NodeId
{
public NodeIdTestClass()
{
}
public new virtual object Identifier
{
get => base.Identifier;
}
public new virtual ushort NamespaceIndex
{
get => base.NamespaceIndex;
}
public new virtual bool IsNullNodeId
{
get => base.IsNullNodeId;
}
}
//Arrange
var nodeIdMock = new Mock<NodeIdTestClass>() { CallBase = true };
nodeIdMock.Setup(x => x.Identifier).Returns(nodeIdMock.Object.Identifier);
nodeIdMock.Setup(x => x.NamespaceIndex).Returns(1);
nodeIdMock.Setup(x => x.IsNullNodeId).Returns(false);
_nodemanager.SetNamespaces(new string[] { "0", "1", "2" });
//Act
var result = _nodemanager.GetManagerHandle(nodeIdMock.Object);
The problem :
Is there something wrong with code?
Do you need a mock?
Wouldn't this be enough?
var nodeId = new NodeId(value: 17, namespaceIndex: 1);
var result = _nodemanager.GetManagerHandle(nodeId);

Moq keeps throwing null reference exception

I am new to Moq having used Rhino mocks for a while. I am trying to stub a method so that is returns the information I expect but the actual line of code when running the test returns a null reference exception. Am I missing something obvious here? Below is my code:
public void GetResSystemClients(ResSystem resSystem)
{
ResSystemDetail = new ResSystemDetails() {ResSys = resSystem};
//RETURNS NULL REFERENCE EXCEPTION
var resClients = FileReader.ReadFile((c) => c.Where(x =>
x.ReservationSystem.Replace(" ", "").ToLowerInvariant().Contains(resSystem.ToString().ToLowerInvariant())));
ResSystemDetail.ResSystemClients = resClients
.Select(y => new ResSystemClient() {ClientCode = y.ClientCode, ClientName = y.ClientName})
.OrderBy(z => z.ClientCode).ToList();
}
Test Code
[SetUp]
public void SetUp()
{
mockFileReader = new Mock<IClientLookUpFileReader>(MockBehavior.Default);
sut = new ClientLookupModel();
}
[TestCase(ResSystem.Test)]
public void When_GetResSystemCalled_With_ResSystem_Return_CorrectClients(ResSystem system)
{
//Arrange
mockFileReader.Setup(x =>
x.ReadFile(It.IsAny<Func<List<ExtraClientInfo>, IEnumerable<ExtraClientInfo>>>()))
.Returns(new List<ExtraClientInfo>
{
new ExtraClientInfo
{
ClientName = "Test",
ClientCode = "XX"
},
new ExtraClientInfo
{
ClientName = "Test1",
ClientCode = "X1"
},
new ExtraClientInfo
{
ClientName = "Test2",
ClientCode = "X2"
},
});
//Act
sut.GetResSystemClients(system);
}
Read file code
public interface IClientLookUpFileReader
{
T ReadFile<T>(Func<List<ExtraClientInfo>, T> predicateFunc);
}
public class ClientLookUpFileReader : IClientLookUpFileReader
{
private const string filePath = "D:/PersistedModels/ClientInfo.json";
T IClientLookUpFileReader.ReadFile<T>(Func<List<ExtraClientInfo>, T> predicateFunc)
{
if (File.Exists(filePath))
{
var clientInfoList = new JavaScriptSerializer().Deserialize<List<ExtraClientInfo>>(System.IO.File.ReadAllText(filePath));
return predicateFunc(clientInfoList);
}
throw new Exception($"File not found at path {filePath}");
}
}

How can I unit test a "greater than" validation created with fluent validation?

I have a property like the following:
RuleFor(c => c.foo).GreaterThan(0);
In the docs of fluent validation, they specify that if I cannot make use of "ShouldHaveValidationErrorFor" method, I could make some assertions with the "Validate" method, but I can't wrap my head around this
All I got is something along this lines:
public void Should_Have_Error_When_Foo_Isnt_Greater_Than_Zero()
{
var bar = new Bar
{
Foo = -1
};
var result = validator.TestValidate(bar);
//Assert.True(bar.Foo > 0, ??)
}
You can do it both ways.
Based on the information provided, assuming your Bar class and BarValidator look something like the following:
public class Bar
{
public int Foo { get; set; }
}
public class BarValidator : AbstractValidator<Bar>
{
public BarValidator()
{
RuleFor(c => c.Foo).GreaterThan(0);
}
}
...I'd normally just do it against the validator, it's neater. The following code tests both a pass and fail state.
public class BarValidatorTests
{
[Test]
public void Foo_Zero_HasValidationError()
{
var validator = new BarValidator();
var dto = new Bar { Foo = 0 };
validator.ShouldHaveValidationErrorFor(x => x.Foo, dto);
}
[Test]
public void Foo_One_DoesNotHaveValidationError()
{
var validator = new BarValidator();
var dto = new Bar { Foo = 1 };
validator.ShouldNotHaveValidationErrorFor(x => x.Foo, dto);
}
}
If you do want to use the TestValidate method, and there are cases where you do want to do it (I use it when my class has a collection of child objects, and I want to test a validation rule on a specific child object), then then following is functionally equivalent to the previous:
public class BarValidatorTestsUsingTestValidate
{
[Test]
public void Foo_Zero_HasValidationError()
{
var validator = new BarValidator();
var dto = new Bar { Foo = 0 };
var validationResults = validator.TestValidate(dto);
validationResults.ShouldHaveValidationErrorFor(x => x.Foo);
}
[Test]
public void Foo_One_DoesNotHaveValidationError()
{
var validator = new BarValidator();
var dto = new Bar { Foo = 1 };
var validationResults = validator.TestValidate(dto);
validationResults.ShouldNotHaveValidationErrorFor(x => x.Foo);
}
}

Moq Insert/Update with new Object initialization

public class UserService
{
IUserRepo userRepo;
UserService(IUserRepo repo)
{
userRepo = repo;
}
void AddUser(JsonData data)
{
User user = new User()
{
Name = data.name,
Number = data.Number
};
userRepo.Insert(user);
int id = user.id;
}
}
id is 0 when a unit test case is debugged, but when it is a proper call it returns proper primary key i.e. 1, 2, 3, etc.
Mock
class TestCases
{
Mock<IUserRepo> mockUserRepo = new Mock<IUserRepo>();
[Test]
public void test1()
{
//Arrange
JsonData obj = new JsonData()
{
Name = "Jane",
Number = "0563722992"
}
User dumpUser= new User()
{
Name = "Def",
Number = "8111"
};
mockUserRepo
.Setup(x => x.Insert(It.IsAny<User>()))
.Callback(() => dumpUser.Id = 1);
//Act
UserService u = new UserService(mockUserRepo.Object);
u.AddUser(obj);
//Assert
}
}
While debugging the unit test it seems that callback is unable to change the id to 1 when it passes through the method Insert().
Can anybody help how to tackle with this issue?
There is no need for
User dumpUser= new User()
{
Name = "Def",
Number = "8111"
};
As the method under test creates/initializes it's own instance within.
Capture the passed argument in the call back and update the desired member there
//...
userRepo
.Setup(x => x.Insert(It.IsAny<User>()))
.Callback((User arg) => arg.Id = 1);
//...

Unit Test Mocking an IHttpActionResult GetId method

I am creating some unit tests for a controller I have however I ran into a problem.
Basically I have the following:-
The Controller Method :-
[ResponseType(typeof(Attrib))]
public IHttpActionResult GetAttrib(int id)
{
var attrib = _attribsRepository.GetAttrib(id);
if (attrib == null)
{
return NotFound();
}
return Ok(attrib);
}
Its a simple Web API 2.0 method.
Then I have the Repository :-
public Attrib GetAttrib(int id)
{
return DbSet.FirstOrDefault(x=>x.Id == id);
}
And finally the Test Method:-
public class AttribsControllerTests
{
public Mock<IAttribsRepository> _attribsRepositoryMock;
public List<Attrib> AttribList;
public AttribsController AttribsController;
[SetUp]
public void Init()
{
_attribsRepositoryMock = new Mock<IAttribsRepository>();
AttribList = new List<Attrib>
{
new Attrib()
{
Id = 1,
AttributeId = "Cro",
AttributeName = "Crossing",
AttributeType = "Tech",
AttributeValue = 1
},
new Attrib()
{
Id = 2,
AttributeId = "Dri",
AttributeName = "Dribbling",
AttributeType = "Tech",
AttributeValue = 2
},
new Attrib()
{
Id = 3,
AttributeId = "Fin",
AttributeName = "Finishing",
AttributeType = "Tech",
AttributeValue = 3
}
};
}
[Test]
public void Get_Check_That_Id1_Returns_Crossing()
{
//Arrange
_attribsRepositoryMock.Setup(t => t.GetStaticAttribs()).Returns(AttribList.AsQueryable());
//Act
var attribsController = new AttribsController(_attribsRepositoryMock.Object);
var result = attribsController.GetAttrib(1) as OkNegotiatedContentResult<Attrib>;
//Assert
Assert.IsNotNull(result);
Assert.AreEqual(AttribList[0].AttributeName, "Cor");
}
}
For some reason, the result is always null, so its not hitting the controller correctly.
Any ideas why this could happen? When debugging, the correct Mock Repository is hitting the controller, and it should have the 3 entries in it.
Any help will be very much appreciated.
You setup GetStaticAttribs but it is used nowhere in the example you showed. You were suppose to setup IAttribsRepository.GetAttrib
Based on your example
[Test]
public void Get_Check_That_Id1_Returns_Crossing() {
//Arrange
var id = 1;
_attribsRepositoryMock.Setup(t => t.GetAttrib(id)).Returns(AttribList[0]);
var attribsController = new AttribsController(_attribsRepositoryMock.Object);
//Act
var result = attribsController.GetAttrib(id) as OkNegotiatedContentResult<Attrib>;
//Assert
Assert.IsNotNull(result);
Assert.IsNotNull(result.Content);
Assert.AreEqual(result.Content.AttributeName, "Crossing");
}

Categories

Resources