Why isn't this NUnit Test Catching My Exception? - nunit

I've got a simple NUnit test:
[Test]
public void Invalid_ID_throws_an_exception()
{
var zero = 0;
var negativeNumber = -9;
Assert.Throws<ArgumentOutOfRangeException>(() => edsp.PersonInfoById(zero));
Assert.Throws<ArgumentOutOfRangeException>(() => edsp.PersonInfoById(negativeNumber));
}
and the tested method:
public IEnumerable<PersonInfo> PersonInfoById(int id)
{
if (id <= 0)
throw new ArgumentOutOfRangeException(nameof(id), "ID must be greater than zero");
yield return new PersonInfo();
}
... but the test fails on the first assertion because the result is null, rather than the expected ArgumentOutOfRangeException:
Message:
Expected: <System.ArgumentOutOfRangeException>
But was: null
What am I doing wrong here?
Edit: also, my debugger isn't stepping into my tested method edsp.PersonInfoById for some reason - steps right over it despite clicking "step into" when debugging.

The test passes if you force the enumeration by calling .ToList() on the result.
For example:
[Test]
public void Invalid_ID_throws_an_exception()
{
var zero = 0;
var negativeNumber = -9;
Assert.Throws<ArgumentOutOfRangeException>(() => edsp.PersonInfoById(zero).ToList());
Assert.Throws<ArgumentOutOfRangeException>(() => edsp.PersonInfoById(negativeNumber).ToList());
}

Related

The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.01

This is function that takes two List<int> and update corresponding tables at database. When I run both functions using threads T1 and T2 , then it shows me exception at the second foreach loop:
"The ObjectContext instance has been disposed and can no longer be
used"
I already used query like
var res = ctx.EmailDBs.Include(x => x.EmailDBid == id);
but it's not working.
Please share something to persist the ctx connection until both methods are executed.
public static void UpdateEmail(List<int> invalidEmailToUpdate, List<int> validEmailToUpdate)
{
using (OnliveMTAEntities ctx = new OnliveMTAEntities())
{
Thread T1, T2;
T1 = new Thread(() =>
{
foreach (int id in invalidEmailToUpdate)
{
var res = ctx.EmailDBs.FirstOrDefault(x => x.EmailDBid == id);
res.Status = 6;
}
});
T1.Start();
Thread.Sleep(100);
T2 = new Thread(() =>
{
foreach (int id in validEmailToUpdate)
{
var res = ctx.EmailDBs.FirstOrDefault(x => x.EmailDBid == id);
res.Status = 7;
}
});
T2.Start();
ctx.SaveChanges();
}
}
You need to wait until both threads T1 and T2 are fully completed. Only then you can save dataContext ctx.SaveChanges();
For that purpose is method called Join() (MSDN). Use it like that:
// previous code here
T2.Start();
// wait for threads to be done
T1.Join();
T2.Join();
// now both of them are done
ctx.SaveChanges();
// end of using(...) and other code
EDIT: I forgot to mention: using both Join(), you can get rid of Thread.Sleep(100);. I believe that this is the reason why you got error on second thread. That call will pause execution of current thread (which will start T2) for 100ms and during that time T1 succeded to complete it's work.

How to check if a web element is displayed without crashing when trying to look for non-existing element?

I want to check id certain element is displayed with selenium, buy when you try to locate certain element like:
val editInvoiceString = driver.findElement(By.xpath( """//*[#id="edit_invoice"]/div[2]/div/div[10]/div[5]/div[1]"""))
editInvoiceString
if (editInvoiceString.isDisplayed)
do something
if the element is not on page the program will be crashed.
its crashing already in the assignment, cause there is a findElement there and its not finding the element
How can I check if it is displayed without crash it?
Just handle the NoSuchElementException:
try {
val editInvoiceString = driver.findElement(By.xpath( """//*[#id="edit_invoice"]/div[2]/div/div[10]/div[5]/div[1]"""));
println("element found");
// check the displayedness
}
catch {
case e: NoSuchElementException => println("no such element");
}
If you use driver.find instead of driver.findElement, it will return an Option, on which you can then call isDefined to verify that the element is found.
Are you using WebBrowser?
you can achieve it by:
public bool IsElementPresent(By by, IWebDriver driver)
{
try
{
driver.FindElement(by);
return true;
}
catch (NoSuchElementException)
{
return false;
}
}
public bool IsElementPresent(By by, IWebDriver driver, int sec)
{
bool itemExist = false;
itemExist = IsElementPresent(by, driver);
while (!itemExist && sec >= 0)
{
thread.Sleep(1);
itemExist = IsElementPresent(by, driver);
sec--;
}
if (sec == -1)
return false;
else
return true;
}
Call:
if(IsElementPresent(By.xpath("""//*[#id="edit_invoice"]/div[2]/div/div[10]/div[5]/div[1]"""),driver,5))
{
//case exist
}
else
{
// case not exist
}
You don't need to use a try-catch clause if you ignore the exception using the Wait class (which extends FluentWait):
Wait wait = new FluentWait(driver)
.withTimeout(30, SECONDS)
.pollingEvery(5, SECONDS)
.ignoring(NoSuchElementException.class);
WebElement foo = wait.until(ExpectedConditions.presenceOfElementLocated(
By.xpath(".//*[#id="edit_invoice"]/div[2]/div/div[10]/div[5]/div[1]"))
);
Use findElements instead of FindElement.
This will return a list of WebElements found. If no elements are found the list will be empty. It would look something like this (Note I'm not a Scala person so the syntax below may be slightly incorrect).
val editInvoiceString = driver.findElements(By.xpath( """//*[#id="edit_invoice"]/div[2]/div/div[10]/div[5]/div[1]"""))
if (editInvoiceString size > 0)
do something

Switch vs SelectMany + TakeUntil

I'm writing an operator that effectively does the same as Switch plus some other stuff. I always understood Switch to effectively be a neat wrapper around SelectMany combined with TakeUntil. However whilst implementing my new extension I've noticed something different about the order of creation/disposal of inner sequences. I'm wondering how I can replicate the order Switch works in since it seems likely we'd always want to dispose the existing inner before creating a new one.
I've written 2 tests to illustrate what I mean.
StandardSwitch will give the following output:
Disposing Inner followed by Creating New Inner
HandCrankedSwitch will give:
Creating New Inner,
Disposing Inner
See example code below:
[TestMethod]
public void StandardSwitch()
{
var outer = Observable.Interval(TimeSpan.FromSeconds(1))
.Do(x => Console.WriteLine("New Outer Value is {0}", x));
var wait = new CountdownEvent(8);
outer
.Select(CreateInner)
.Switch()
.Subscribe(x =>
{
Console.WriteLine("Subscriber Got {0}", x);
wait.Signal();
});
wait.Wait();
Console.WriteLine("Done");
}
[TestMethod]
public void HandCrankedSwitch()
{
var outer = Observable.Interval(TimeSpan.FromSeconds(1))
.Do(x => Console.WriteLine("New Outer Value is {0}", x));
var wait = new CountdownEvent(8);
outer.Publish(x => x.Select(CreateInner).SelectMany(xs => xs.TakeUntil(x)))
.Subscribe(x =>
{
Console.WriteLine("Subscriber Got {0}", x);
wait.Signal();
});
wait.Wait();
Console.WriteLine("Done");
}
internal IObservable<long> CreateInner(long notUsed)
{
return Observable.Create<long>(obs =>
{
Console.WriteLine("Creating New Inner");
var compDis = new CompositeDisposable {Disposable.Create(() => Console.WriteLine("Disposing Inner"))};
var dis = Observable.Interval(TimeSpan.FromSeconds(0.4))
.Do(x => Console.WriteLine("New Inner Value is {0}", x))
.Subscribe(obs);
compDis.Add(dis);
return compDis;
});
}

NUnit & MOQ: Testing a try catch that calls another method when an Exception is caught

I understand that the MOQ framework wasn't really designed to help in this instance, but perhaps you might be able to help...
I have a method that uses a try/catch that calls a notification method whenever an exception is thrown. What I am trying to do is create an integration/unit test that checks to make sure SendNotification is called when any exception is thrown.
Method Under Test:
public virtual void MonitorIntradayBuilds(IIntradayBuilds intradayBuilds)
{
try
{
var intradayBuildFound = intradayBuilds.CheckForIntradayBuilds();
if (intradayBuildFound && !IntradayBuildsComplete && !DailyBuildsFound)
{
IntradayBuildsComplete = intradayBuilds.StartIntradayBuilds();
//should start daily builds?
}
}
catch (Exception ex)
{
SendNotification("MonitorIntradayBuilds threw an exception", ex);
}
}
Test Case:
[Test]
public void it_should_notify_developers_immediately_if_there_is_a_problem_when_checking_for_intraday_builds()
{
//Arrange
var mockDua = new Mock<DUA>();
var mockIB = new Mock<IIntradayBuilds>();
//Act
mockIB.Setup(x => x.CheckForIntradayBuilds()).Throws(new Exception());
mockDua.Object.MonitorIntradayBuilds(mockIB.Object);
//Assert
mockDua.Verify(x => x.SendNotification(It.IsAny<string>(), It.IsAny<Exception>()), Times.Once);
}
I keep hitting a Moq.MockException and then see that SendNotification "expected an invocation on the mock once, but was 0 times..."
I've tried using the [ExpectedException] attribute on the test case, but to no avail. It makes the test pass, but still doesn't call the SendNotification method.
Any ideas?
Solved it.
Turns out you need to set the CallBase property on the System Under Test that you are mocking up.
Test case is now:
[Test]
public void it_should_notify_developers_immediately_if_there_is_a_problem_when_checking_for_intraday_builds()
{
//Arrange
var mockDua = new Mock<DUA>();
var mockIB = new Mock<IIntradayBuilds>();
mockDua.CallBase = true; // <<<< Added this line!
//Act
mockIB.Setup(x => x.CheckForIntradayBuilds()).Throws(new Exception());
mockDua.Object.MonitorIntradayBuilds(mockIB.Object);
//Assert
mockDua.Verify(x => x.SendNotification(It.IsAny<string>(), It.IsAny<Exception>()), Times.Once);
}
Hopefully someone else finds it helpful :)

Test a method that does something as well as throws an exception

I'm getting started with TDD (and MoQ). I have a method that takes in an Order and creates a unique CustomerId for that Order.
public class CustomerService
{
public CustomerService(IOrderRepository orderRepo)
{
_orderRepo = orderRepo;
}
public string Create(Order order)
{
//1. Save the Order that comes in, irrespective of being valid or not.
_orderRepo.Save(order);
//2. If the order is invalid, throw an exception.
if (!isValid(order))
throw new ArgumentException();
//3. Create a Customer, generate a unique CustomerId and return that.
return createCustomerAndGenerateCustomerId(order);
}
}
The following test doesn't seem to be working correctly:
[Test]
[ExpectedException(typeof(ArgumentException))]
public void Create_WhenPassedInvalidOrder_StillPersistsIt()
{
//Arrange
var order = new Order(); //This is invalid, as it has some mandatory fields missing
var mockOrderRepo = new Mock<IOrderRepository>();
var customerService = new CustomerService(mockOrderRepo.Object);
//Act
customerService.Create(order); //This should call Save() on the order repo, but still throw an exception.
//Assert
mockOrderRepo.Verify(o => o.Save(order), Times.Once());
}
This test is always passing, even if I don't call _orderRepo.Save(). What am I doing wrong?
You cannot use ExpectedException in this scenario because Nunit will try/catch the exception on the test level so your mockOrderRepo.Verify never gets called.
So you manually need to try catch your customerService.Create call - and if you want manually assert on the thrown exception - or you the Assert.Throws if you're using Nunit 2.5 or higher:
[Test]
public void Create_WhenPassedInvalidOrder_StillPersistsIt()
{
//Arrange
var order = new Order();
var mockOrderRepo = new Mock<IOrderRepository>();
var customerService = new CustomerService(mockOrderRepo.Object);
//Act
Assert.Throws<ArgumentException>(() => customerService.Create(order));
//Assert
mockOrderRepo.Verify(o => o.Save(order), Times.Once());
}