I have a simple function that takes Client and Supplier data and then calculates tax based on where they live and other information:
static int CountTax(Supplier tiek, Client kl, bool same_country)
{
if ( !tiek.is_PVM_payer)
return 0;
else
{
if (!kl.EU)
return 0;
else
{
if (same_country)
return kl.x;
else
{
if (kl.is_PVM_payer)
return 0;
else
return kl.x;
}
}
}
}
Now I am required to write tests for this function. It is the first time I am encountering tests. I am using XUnit testing. And my test class looks like this:
using System;
using Xunit;
namespace CountTax_tests
{
public class UnitTest1
{
[Theory]
[InlineData(typeof(Client))]
public void Tax_is_0()
{
// arrange
int expectedVal = 0;
int actualVal;
/// act
actualVal = MyProgram.MyprogramCode.CountTax(supplier, client, same_country);
// assert
Assert.Equal(expectedVal, actualVal);
}
[Fact]
public void PVM_is_x()
{
int expectedVal = x;
int actualVal;
actualVal = MyProgram.MyprogramCode.CountTax(supplier, client, same_country);
Assert.Equal(expectedVal, actualVal);
}
}
}
But how do I pass my Client and Supplier parameters to that test? Please help me and lead on a path because I am completely new and nothing is clear to me even after many tutorials...
Maybe I have to use [Theory]? Or maybe [Fact]? Or maybe it is impossible to pass classes as parameters?
Also, [InlineData(typeof(Client))] is being underlined in red and is not working.
Related
How to get the parameters count which is passing to the function using Nunit mocking for assertion and that function called inside another function.
For e.g:
public class TestClass
{
public string Name {get;set;}
public int Id {get;set;}
}
public void ProcessData(IEnumerable<EventData> events)
{
List<TestClass> testClasses = new();
events.ForEach(msg => {
var testClass = JsonConvert.DeserializeObject<TestClass>(msg.EventBody.ToString());
if(testClass != null)
{
testClasses.Add(testClass);
}
});
if(testClasses.Count > 0)
{
BulkUpdateData(testClasses);
}
}
public void BulkUpdateData(List<TestClass> testClasses)
{ ... }
Now, I need to do unit testing this "ProcessData" method.
For this using NUnit framework in .Net 6.0.
I can pass test data to "ProcessData" method by mocking while writing unit test cases.
But here my case is,
Consider now I'm passing 10 values in a list to "ProcessData". In that only 8 got passed to "BulkUpdateData" method since 2 values are not got deserialized due to invalid data.
Here how to get this BulkUpdateData got 8 values inside the "ProcessData" method.
I need to get this count value for assertion.
Kindly suggest on this.
Your ProcessData() method needs to return something. Either an int representing the count of processed testclasses, or List<TestClass>.
With your ProcessData() method now returning something, you can then go ahead and write your asserts, knowing exactly how many testclasses were passed to BulkUpdateData() method.
public IEnumerable<TestClass> ProcessData(IEnumerable<EventData> events)
{
List<TestClass> testClasses = new();
events.ForEach(msg => {
var testClass = JsonConvert.DeserializeObject<TestClass>(msg.EventBody.ToString());
if (testClass != null)
{
testClasses.Add(testClass);
}
});
if (testClasses.Count > 0)
{
BulkUpdateData(resultOfProcessData);
}
return testClasses;
}
If I misunderstood your question and actually, you want to unit test BulkUpdateData() method, in your [TestFixture] you could add an instance variable to hold either the count or the list of TestClass objects. And you could take advantage of the [OrderAttribute] and organize your tests like this:
[TestFixture]
public class UnitTests
{
List<TestClass> resultOfProcessData = new();
[Test]
[Order(1)]
public void ProcessDataUnitTest()
{
resultOfProcessData = ProcessData(events);
}
[Test]
[Order(2)]
public void BulkUpdateDataUnitTest()
{
if (resultOfProcessData.Count > 0)
{
BulkUpdateData(resultOfProcessData);
}
}
public IEnumerable<TestClass> ProcessData(IEnumerable<EventData> events)
{
List<TestClass> testClasses = new();
events.ForEach(msg => {
var testClass = JsonConvert.DeserializeObject<TestClass>(msg.EventBody.ToString());
if (testClass != null)
{
testClasses.Add(testClass);
}
});
return testClasses;
}
public void BulkUpdateData(List<TestClass> testClasses)
{ ... }
}
Hope this helps.
I am trying to test a class which instatiates another class within it. It is the instatinated class call I want to mock.
Is this possible or is they a way around it/ simpler way I am missing?
Below I have written up a simpler example which still has the same problemts as my main code.
public interface my_interface
{
int returns_25();
}
public class class_i_want_to_mock : my_interface
{
public int returns_25()
{
// TEST SHOULD FAIL SO NEED MOCK TO PASS THE CASE
return 7645745;
}
}
In another namespace (it has access):
public class class_to_test
{
public static int returns_25()
{
class_i_want_to_mock _tempClass= new class_i_want_to_mock ();
// Will return 7645745 unless moq changes return value
int _temp_int = _tempClass.returns_25()
return _temp_int;
}
}
My test (which fails):
[Test]
public void test_returns_25()
{
// Mock
Mock<my_interface> myMock = new Mock<my_interface>();
myMock.Setup(m => m.returns_25()).Returns(25);
// Act
int return_number = class_to_test.returns_25();
// Assert
Assert.AreEqual(25, return_number);
}
Here is working code thanks to the injection idea from JSteward above.
Code is in same order
public interface my_interface
{
int returns_25();
}
public class class_i_want_to_mock : my_interface
{
public int returns_25()
{
// TEST SHOULD FAIL SO NEED MOCK TO PASS THE CASE
return 7645745;
}
}
Next class, notice the injection of the interface
public class class_to_test
{
public static int returns_25(my_interface _temp_interface)
{
// Will return 7645745 unless moq changes return value
int _temp_int = _temp_interface.returns_25()
return _temp_int;
}
}
And the test. Note the object of the Mock class has to be used (myMock.Object)
[Test]
public void test_returns_25()
{
// Mock
Mock<my_interface> myMock = new Mock<my_interface>();
myMock.Setup(m => m.returns_25()).Returns(25);
// Act
int return_number = class_to_test.returns_25(myMock.Object);
// Assert
Assert.AreEqual(25, return_number);
}
I have like below.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace Syncfusion.Gitlab
{
public class Branches
{
public void CreateBranch(List<string> projectName, string sourceBranch, string destinationBranch)
{
}
public void CreateTag(List<string> projectName, string sourceBranch,string tagname)
{
}
public static List<string> GetBranchList(string projectId)
{
}
public static List<ProjectData> GetProjectList()
{
}
}
public class ExcelOperation
{
public void GenerateExcel(List<ProjectDetails> finalExcelData, List<string>projectUrl,List<string>tagsorBranchUrl)
{
}
}
}
I can able to test the method and got the positive output. But I do not know how to test these two method public static List<string> GetBranchList(string projectId), public static List<ProjectData> GetProjectList()
My sample test code is below. Below method is successfully passed in NUnit test.
[TestMethod]
public void CreateTags()
{
List<string> project = new List<string>();
project.Add("test1");
string sourceBranch = "master";
string tagsName = "v1.0.0";
branch.CreateTag(project, sourceBranch, tagsName);
}
How can I test the that two methods?
Update:
I can get the answer with the help of first answer. But Now I have anouther doubt.
How could I test for wrong input? I mean I know that the input I was given Is wrong but I need the green tick mark for that testing. That means the input given is wrong so the output also wrong therfore the testing is right.
In my below image. I need public void GetBranchListforWrongInput() also green tick mark.
How could I do it?
Unit testing static method is pretty much as same as testing non-static methods. It might get complex based on what logic you have in the static method.
But simplest way for your case would be as following.
[TestMethod]
public void TestGetBranchList()
{
string projectId = "someProjectId";
var result = Branches.GetBranchList(projectId);
//Assert if result has expected result.
}
[TestMethod]
public void TestGetProjectList()
{
var result = Branches.GetProjectList();
//Assert if result has expected result.
}
[TestMethod]
public void TestCreateBranch()
{
//Prepare TestData
List<string> projectName = new List<string> {"someProject"};
string sourceBranch = "sourceBranch"
string destinationBranch = "destBranch";
Branches branchesObj = new Branches();
// Call method by passing the test data.
branchesObj.CreateBranch(projectName, sourceBranch, destinationBranch);
}
This should help you resolve your issue.
I have the following class which is a TestFixture which has one test and a TestCaseSource that produces my TestCases. My test case actually contain both the actual result and the expected result which is wrapped in an Object called TestCaseEntity
namespace SomeNamespace
{
[TestFixture]
public class MyTest
{
static Client client;
static List<string> userIds = new List<string>();
[TestFixtureSetUp]
public void Init()
{
// Set up a client
client = new Client("server address"); // a HTTP client
// populate a List of userIds from a local text test file
userIds.Add(GetAllIdsFromTxtFile());
}
[Test, TestCaseSource(typeof(MyTestCaseEntityFactory), "MyTestCases")]
public void CheckExpectations(TestCaseEntity testCaseEntity)
{
if (!testCaseEntity.IsIdentical)
{
Log.Error("Log some shit");
Assert.Fail("fail assertions");
}
}
public class MyTestCaseEntityFactory
{
public static IEnumerable<TestCaseEntity> MyTestCases
{
get
{
foreach (string id in userIds)
{
// use the client and get the results, construct the new TestCaseEntity(...) and return;
yield return new TestCaseEntity("actualValue", "expectedValue resulting from the server call");
}
}
}
}
}
}
When I run my Test, I get the following error which is unfortunately not very helpful!
System.NullReferenceException : Object reference not set to an instance of an object.
Any suggestions on what I might have done wrong?
You foreach over allSalesDEDealIds but you seem to have not included it in your code example. It might be that this is the NullRefExceptionin your code?
Im trying to mock a method, it compiles without errors, but smth strange happens when i run a test. Actually method doesnt mock or maybe I dont understand smth...(
Here's a code:
public class Robot
{ ....
public virtual bool range(IObs ob, double range)
{
double dist = ob.distanceSq(this);
if (dist < range)
return true;
else
return false;
}
}
...
public interface IObs
{
double distanceSq(Robot r);
}
...
Unit Test:
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
MockRepository mocks = new MockRepository();
IObs obstacleMock = mocks.CreateMock<IObs>();
Robot r = new Robot();
Expect.Call(obstacleMock.distanceSq(r)).IgnoreArguments()
.Constraints(Is.Anything())
.Return(5.5);
Assert.IsTrue(r.range(obstacleMock, 0.5));
}
}
I mock distanceSq().
When I debug my test, i see that ob.distanceSq(this) is 0.0. (not 1.5).
What's wrong?
Your code does not actually use mock you created - as you can change Obstacle to IObjs as argument of range and than pass mock instead of new instance of Obstacle:
public virtual bool range(IObjs ob, double range)....
class Obstacle : IObjs ...
Assert.IsTrue(r.range(obstacleMock, 0.5));
I would recommend that you upgrade your RinoMocks version to 3.6 and use the new syntax.
Additionally if you are using a mock for IObs, you may as well verify that the distanceSq method is called.
I have left the verification of the parameters in the distanceSq method out of this code, but you could ensure that the correct Robot instance is passed in.
The unit test will still fail however, as 5.5 is greater than 0.5
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Rhino.Mocks;
namespace Rhino
{
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
var r = new Robot();
var obstacleMock = MockRepository.GenerateMock<IObs>();
obstacleMock.Expect(x => x.ditanceSq(Arg<Robot>.Is.Anything)).Return(5.5);
//use this line to ensure correct Robot is used as parameter
//obstacleMock.Expect(x => x.ditanceSq(Arg<Robot>.Is.Equal(r))).Return(5.5);
var result = r.range(obstacleMock, 0.5);
obstacleMock.VerifyAllExpectations();
Assert.IsTrue(result);
}
}
public class Robot
{
public virtual bool range(IObs ob, double range)
{
return ob.ditanceSq(this) < range;
}
}
public interface IObs
{
double ditanceSq(Robot r);
}
}