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?
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 wrote the following test case to illustrate my problem using Rhino Mocks:
[TestClass]
public class Tester
{
public class TestList<T> : List<T>
{
public override bool Equals(object obj)
{
// obj is an empty list here??
return base.Equals(obj);
}
}
public interface IStubbedInterface
{
void DoSomethingWithList(TestList<int> list);
}
public class ClassToTest
{
public IStubbedInterface TheStub { get; set; }
public void Run()
{
var list = new TestList<int> { 1, 2 };
TheStub.DoSomethingWithList(list);
list.Clear();
}
}
public bool Match(TestList<int> arg)
{
// Here arg is an empty list??
return arg == new TestList<int> { 1, 2 };
}
[TestMethod]
public void Test()
{
var classToTest = new ClassToTest();
classToTest.TheStub = MockRepository.GenerateMock<IStubbedInterface>();
classToTest.Run();
classToTest.TheStub.AssertWasCalled(
x => x.DoSomethingWithList(new TestList<int>() { 1, 2 }));
//x => x.DoSomethingWithList(Arg<TestList<int>>.Matches(arg => Match(arg))));
}
}
The test case will fail on the AssertWasCalled() line, no matter if I compare the list directly or using the Arg<>.Matches(..) syntax. I also tried with MockRepository.GenerateStub<>(..) instead of GenerateMock<>(..), which also fails. It fails because of the list.Clear(); line after calling DoSomethingWithList(), which results in the list also being empty at the time of AssertWasCalled(). Is this a bug with RhinoMocks? I would have assumed that RhinoMocks would record a snapshot of the argument somehow when the asserted function was called, but it looks like RhinoMocks keeps using the same object?
In the real case where I encountered this problem the argument of the function I was testing was wrapped in a using() statement, which lead to the same effect of AssertWasCalled not being able to test the arguments passed.
Looks like using the Expect()/VerifyAllExpectations() pattern works better for this test scenario. Changing the test case to the below code will pass.
This is rather unfortunate as I much prefer using AssertWasCalled(), however as it stands it is rather unreliable.
[TestMethod]
public void Test()
{
var classToTest = new ClassToTest();
classToTest.TheStub = MockRepository.GenerateMock<IStubbedInterface>();
classToTest.TheStub.Expect(
x => x.DoSomethingWithList(new TestList<int>() { 1, 2 }));
classToTest.Run();
classToTest.TheStub.VerifyAllExpectations();
}
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.
Please see the update at the bottom!
I am setting up my framework and currently have 4 Tests. Individually they all run like a charm. However when I try to run all 4 in parallel (I have set up the Parallelizable attribute up correctly and am calling tests from different classes not within the same method) I am consistently getting several errors that seem to jump around each test. These are the messages that I am getting each run:
Again These objects are found when the tests are run individually. I am not sure what code I need to show in order to help. Please advise.
UPDATE** #Chris my suspicions are the same. I think my tests are confusing the same driver when looking for objects. If that is the case can someone please advise how to better handle this, my browser class is what is calling the driver.
public static class Browser
{
private static IWebDriver driver;
private static string baseURL = "someURL";
public static ISearchContext Driver { get { return driver; } }
internal static bool WaitUntilElementIsDisplayed(By element, int timeout)
{
for (int i = 0; i < timeout; i++)
{
if (ElementIsDisplayed(element))
{
return true;
}
Thread.Sleep(1000);
}
return false;
}
internal static IWebElement FindElement(By by)
{
return driver.FindElement(by);
}
public static bool ElementIsDisplayed(By element)
{
var present = false;
driver.Manage().Timeouts().ImplicitlyWait(System.TimeSpan.FromSeconds(0));
try
{
present = driver.FindElement(element).Displayed;
}
catch (NoSuchElementException)
{ }
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));
return present;
}
public static void Initialize()
{
var options = new InternetExplorerOptions();
options.IntroduceInstabilityByIgnoringProtectedModeSettings = true;
options.EnsureCleanSession = true;
options.IgnoreZoomLevel = true;
driver =
new InternetExplorerDriver(
#"C:Myfilepath",
options, TimeSpan.FromMinutes(10));
Goto("");
}
public static void CleanUp()
{
driver.Close();
driver.Quit();
}
public static void Goto(string URL, bool userBaseURL = true)
{
if (userBaseURL)
driver.Navigate().GoToUrl(string.Format("{0}/{1}", baseURL, URL));
else
driver.Navigate().GoToUrl(URL);
}
}
Newest Update: per the recommendation I have removed the static references but could someone help me with the syntax on creating an instance of the driver within my current code
public class Pages
{
private T GetPage<T>() where T : new()
{
var page = new T();
PageFactory.InitElements(Browser.Driver, page);
return page;
}
public LoginPage Login
{
get { return GetPage<LoginPage>(); }
}
public RegisterPage Register
{ get { return GetPage<RegisterPage>(); } }
public SearchPage Search
{ get { return GetPage<SearchPage>(); } }
}
I am not sure how to create an instance of Browser.Driver Please help!
Remove all references to "static" in your class and create an instance of the class in each test to fix your issue.
...Now change your Page class to accept the driver in the constructor
public class Pages
{
private readonly ISearchContext _context;
public Pages(ISearchContext context)
{
_context = context;
}
private T GetPage<T>() where T : new()
{
var page = new T();
PageFactory.InitElements(_context, page);
return page;
}
public LoginPage Login
{
get { return GetPage<LoginPage>(); }
}
public RegisterPage Register
{ get { return GetPage<RegisterPage>(); } }
public SearchPage Search
{ get { return GetPage<SearchPage>(); } }
}
... then in your test method
var browser = new Browser();
var page = new Page(browser.Driver);
Sorry. Been away and noticed your updates.
I have a separate class helper that I use to return my web driver. I’m using chrome driver and (headless) unit driver, which on my machines polices requires several params to get it running, so a class in its own right makes senses to me. E.g. WebDriverHelper.java. This has several static methods that returns a new instance of the driver of interest.
E.g.
WebDriver myDriver = WebDriverHelper.ChromeDriver();
My ChromeDriver method returns a new driver.
E.g.
return new ChromeDriver;
If you need more detail, let me know and I’ll copy some of my classes when I get in work tomorrow.
I am using TestCaseSource with NUnit. The below code generates IEnumerable of TestCaseData that represent an archive entry, which is an input for a test.
private class GithubRepositoryTestCasesFactory
{
private const string GithubRepositoryZip = "https://github.com/QualiSystems/tosca/archive/master.zip";
public static IEnumerable TestCases
{
get
{
using (var tempFile = new TempFile(Path.GetTempPath()))
using (var client = new WebClient())
{
client.DownloadFile(GithubRepositoryZip, tempFile.FilePath);
using (var zipToOpen = new FileStream(tempFile.FilePath, FileMode.Open))
using (var archive = new ZipArchive(zipToOpen, ZipArchiveMode.Read))
{
foreach (var archiveEntry in archive.Entries.Where(a =>
Path.GetExtension(a.Name).EqualsAny(".yaml", ".yml")))
{
yield return new TestCaseData(archiveEntry);
}
}
}
}
}
}
[Test, TestCaseSource(typeof (GithubRepositoryTestCasesFactory), "TestCases")]
public void Validate_Tosca_Files_In_Github_Repository_Of_Quali(ZipArchiveEntry zipArchiveEntry)
{
var toscaNetAnalyzer = new ToscaNetAnalyzer();
toscaNetAnalyzer.Analyze(new StreamReader(zipArchiveEntry.Open()));
}
The above code fails on the following line:
zipArchiveEntry.Open()
with an exception:
System.ObjectDisposedException "Cannot access a disposed object.
Object name: 'ZipArchive'."
Is there any way to control the disposing of objects created for test data case?
The problem is that the ZipArchive and its children are being disposed of at the end of the using block.
Try rigging up something like this within your fixture fixture:
// MyDisposable an IDisposable with child elements
private static MyDisposable _parent;
// This will be run once when the fixture is finished running
[OneTimeTearDown]
public void Teardown()
{
if (_parent != null)
{
_parent.Dispose();
_parent = null;
}
}
// This will be run once per test which uses it, prior to running the test
private static IEnumerable<TestCaseData> GetTestCases()
{
// Create your data without a 'using' statement and store in a static member
_parent = new MyDisposable(true);
return _parent.Children.Select(md => new TestCaseData(md));
}
// This method will be run once per test case in the return value of 'GetTestCases'
[TestCaseSource("GetTestCases")]
public void TestSafe(MyDisposable myDisposable)
{
Assert.IsFalse(myDisposable.HasChildren);
}
The key is to set the static member when creating the test case data, then disposing of it on the fixture tear down.