TypeScript Generic Collection: List - list

I am trying to learn TypeScript, and need some advice on implementing generic collection types. I put the dictionary and HashSet in another question, here I'd like any advice on my list type.
Especially the ForEach-Operation looks a bit strange. I think I found it in another question here, and "improved" by returning true or false to give feedback if the iteration was stopped early or completed.
import { IForEachFunction } from "./IForEachFunction"
export class List<T> {
private _items: Array<T>;
public constructor() {
this._items = [];
}
public get Count(): number {
return this._items.length;
}
public Item(index: number): T {
return this._items[index];
}
public Add(value: T): void {
this._items.push(value);
}
public RemoveAt(index: number): void {
this._items.splice(index, 1);
}
public Remove(value: T): void {
let index = this._items.indexOf(value);
this.RemoveAt(index);
}
public ForEach(callback: IForEachFunction<T>): boolean {
for (const element of this._items) {
if (callback(element) === false) {
return false;
}
}
return true;
}
}
The ForEach-Iteration relies on an interface from another file:
export interface IForEachFunction<T> {
(callback: T): boolean | void;
}
You would use my list and the ForEach-Method like this:
let myList: List<a_type> = new List<a_type>();
let completed: boolean = myList.ForEach(xyz => {
// do something with xyz
return false; // aborts the iteration
return true; // continues with the next element
});
if (completed) // we can see what happened "during" the iteration
I think this is not bad, but I'd appreciate any input. I am not sure if I use the === correctly.
Another question which I really like to know: How could I define a function with the interface IForEachFunction? I do not really "re-use" that interface visibly, I always declare an anonymous method as shown above. If I wanted to call a method having the interface definition, is that possible?
Thanks!
Ralf

One problem I see is that you have an interface instance:
callback: IForEachFunction<T>
This contains a method called
callback()
But you only call callback once. You would have call callback() method inside your interface:
callback.callback()
Also your code looks like it is inspired by C# or Java. In TypeScript you would often just use an array. This simplifies certain code constructs.

Related

JUnit 5: Assert an exception is thrown fails with an error

I am working on writing unit test cases for my DAO using the Junit5. I want to test whether the BadRequestException is thrown when maximum template reached and check whether NotFoundException is thrown when template is not found. But I am getting the following exception:
org.mockito.exceptions.misusing.InvalidUseOfMatchersException: You cannot use argument matchers outside of verification or stubbing.
My code:
TemplateDao.java:
#Transactional(readOnly = true)
public MyTemplateDetailsView getTemplateDetails(Long templateId) {
Session session = sessionFactory.getCurrentSession();
MyTemplate myTemplate = getTemplate(templateId);
if (null == myTemplate || myTemplate.getStatus() != TemplateStatus.ACTIVE.value) {
throw new NotFoundException("template.not.found");
}
Integer templatesCount = getTempletsCount(templateId);
if (templatesCount > templateLimit) {
LOGGER.info("max template count reacged");
throw new BadRequestException("template.limit.exceded");
}
}
TemplateDaoTest.java:
#Test
void getTemplateDetails_ThrowsNotFoundException_IfTemplateNotinActiveStatus() {
Assertions.assertThrows(NotFoundException.class, () -> {
when(templateDao.getTemplate(anyLong())).thenReturn(null);
});
}
#Test
public void getTemplateDetails_ThrowsBadRequestException_IfTemplateLimitExceeded() {
Integer limit = 100;
assertThrows(BadRequestException.class, () -> {
when(templateDao.getTempletsCount(anyLong())).thenReturn(limit);
templateDao.getTemplateDetails(anyLong);
});
}
I suspect the problem is in the following block of code:
assertThrows(BadRequestException.class, () -> {
when(templateDao.getTempletsCount(anyLong())).thenReturn(limit);
templateDao.getTemplateDetails(anyLong);
});
I'm not sure where the anyLong comes from, so I'll make an assumption that you meant anyLong(), as in org.mockito.ArgumentMatchers.anyLong.
If so, the problem with this is that you're trying to use a Matcher instead of a concrete value outside of stubbing context (i.e. outside of the specification of what method should return when called).
You need to pass in a proper Long, i.e. 150L (or whatever is larger than templateLimit) when you're calling your stubbed method. For example:
assertThrows(BadRequestException.class, () -> {
when(templateDao.getTempletsCount(anyLong())).thenReturn(limit);
templateDao.getTemplateDetails(150L); // note the concrete value
});
It's actually fairly trivial to reproduce if you're inclined to do so (I'm using JUnit 4, but it should be okay with JUnit 5, too):
public class MatchersTest {
#Test
public void testConversion() {
Converter converter = new Converter();
when(converter.from(anyLong())).thenReturn("1");
converter.from(anyLong());
}
private static class Converter {
String from(Long number) {
return String.valueOf(number);
}
}
}

Confused about PhpSpec stubs and mocks again

I'm building a Laravel 5 application at the moment and have gotten myself confused about how to mock things in PhpSpec.
I'm building a schedule times validator that requires the intended schedule to be checked against all current schedules and see if there's any overlap (events are not allowed to overlap).
I need to pull in the schedules in question so I can test against them. At the moment it's a very basic whereBetween query, but it's going to get a lot more complicated as there'll be recurring schedules to check against as well.
So here's my stripped down class. I really just want to test the doesNotOverlap function.
use App\Schedule;
class ScheduleTimesValidator
{
protected $schedule;
public function __construct(Schedule $schedule)
{
$this->schedule = $schedule;
}
public function doesNotOverlap($slug, $intended)
{
$schedules = $this->getSchedulesBetween($slug, $intended);
if(empty($schedules)) return true;
return false;
}
protected function getSchedulesBetween($slug, $intended)
{
// Casting to array to make testing a little easier
return $this->schedule->whereIsRecurring(false)
->ofChurch($slug)
->whereBetween('start', [$intended['start'], $intended['end']])
->get()->toArray();
}
and here's my Spec
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class ScheduleTimesValidatorSpec extends ObjectBehavior
{
protected $validIntended = [
'start' => '2015-12-01 12:00:00',
'end' => '2015-12-01 13:00:00'
];
protected $churchNonRecurringSchedules = [
['start' => '2014-11-20 13:00:00', 'end' => '2014-11-21 14:00:00'],
['start' => '2014-11-23 10:36:07', 'end' => '2014-11-23 11:36:07'],
];
function let($schedule)
{
$schedule->beADoubleOf('App\Schedule');
$this->beConstructedWith($schedule);
}
function it_is_initializable()
{
$this->shouldHaveType('App\Validation\ScheduleTimesValidator');
}
function it_should_return_true_if_it_does_not_overlap($schedule)
{
// $schedule->any()->willReturn([]);
// $schedule->whereIsRecurring()->shouldBeCalled();
// $schedule->whereIsRecurring(false)->ofChurch()->whereBetween()->get()->toArray()->willReturn([]);
// $schedule->willReturn([]);
// $this->getSchedulesBetween('slug', $this->validIntended)->willReturn([]);
$this->doesNotOverlap('slug', $this->validIntended)->shouldReturn(true);
}
// Tear Down
function letgo() {}
}
If I run it like that I get:
! it should return true if it does not overlap
method 'Double\App\Schedule\P8::whereIsRecurring()' not found.
I tried (as you can see) various commented out things to mock what $schedule will return, but that doesn't seem to work.
So I guess I want to mock the protected getSchedulesBetween method in the class, but doing things like $this->getSchedulesBetween($arg, $arg)->willReturn(blah) doesn't work.
Do I need to pull getSchedulesBetween() out of the class and move it into another class and then mock that? Or do I need to push $this->schedule->blah into the doestNotOverlap method so I can mock what $schedule will return?
I don't want to actually test the App\Schedule Laravel Model - I just want to mock what it's returning and will be hardcoding a variety of queries that will be run to get the different model results.
End of a long day here so brain a little zonked.
Update 2014-10-23
So I created a scope on my Schedule model
public function scopeSchedulesBetween($query, $slug, $intended)
{
return $query->whereIsRecurring(false)
->ofChurch($slug)
->whereBetween('start', [$intended['start'], $intended['end']]);
}
Then created a new App\Helpers\ScheduleQueryHelper which instantiated App\Schedule as a variable and added this method:
public function getSchedulesBetween($slug, $intended)
{
return $this->schedule->schedulesBetween($slug, $intended)->get()->toArray();
}
Then updated my spec to do
function let($scheduleQueryHelper)
{
$scheduleQueryHelper->beADoubleOf('App\Helpers\ScheduleQueryHelper');
$this->beConstructedWith($scheduleQueryHelper);
}
function it_should_return_true_if_it_does_not_overlap($scheduleQueryHelper)
{
$scheduleQueryHelper->getSchedulesBetween('slug', $this->validIntended)->willReturn([]);
$this->doesNotOverlap('slug', $this->validIntended)->shouldReturn(true);
}
And back in my ScheduleTimesValidator class did
public function doesNotOverlap($slug, $intended)
{
$schedules = $this->scheduleQueryHelper->getSchedulesBetween($slug, $intended);
if(empty($schedules)) {
return true;
}
return false;
}
And now PhpSpec is mocking that other class ok. However this seems like a very roundabout way to be doing things.

What is meant by parameterization?

While reading one of the articles for Data Driven Testing, I came across a term 'parametrization of a test'. Could someone explain to me what is meant by parameterization here?
Let's see an example with TestNG. Suppose you have function SomeClass.calculate(int value). You want to check the results the function returns on different input values.
With not-parametrized tests you do something like this:
#Test
public void testCalculate1()
{
assertEquals(SomeClass.calculate(VALUE1), RESULT1)
}
#Test
public void testCalculate2()
{
assertEquals(SomeClass.calculate(VALUE2), RESULT2)
}
With parametrized test:
//This test method declares that its data should be supplied by the Data Provider
//named "calculateDataProvider"
#Test(dataProvider = "calculateDataProvider")
public void testCalculate(int value, int result)
{
assertEquals(SomeClass.calculate(value), result)
}
//This method will provide data to any test method that declares that its Data Provider
//is named "calculateDataProvider"
#DataProvider(name = "calculateDataProvider")
public Object[][] createData()
{
return new Object[][] {
{ VALUE1, RESULT1 },
{ VALUE2, RESULT2 },
};
}
This way, TestNG engine will generate two tests from testCalculate method, providing parameters from array, returned by createData function.
For more details see documentation.

Create a Partial Stub in Microsoft Moles

I am pulling my hair out with this one. I have looked and cannot find a simple, clear example of creating and using a partial stub with Microsoft Moles. Maybe I'm missing somethimg, or have my code architected poorly, but I can't seem to get this to work.
Here's my class (simplified):
public class AccountService : IAccountService {
private readonly webServiceProxy IExternalWebServiceProxy;
public AccountService(IExternalWebServiceProxy webServiceProxy) {
this.webServiceProxy = webServiceProxy;
}
public List<AccountModel> GetAccounts(string customerId) {
var returnList = new List<AccountModel>();
var xmlResponse = webServiceProxy.GetAllCustomerAccounts(customerId);
var accountNodes = xmlResponse.SelectNodes("//AccountNodes");
if (accountNodes != null)
{
foreach (XmlNode node in accountNodes)
{
var account = this.MapAccountFromXml(node);
if (!string.IsNullOrEmpty(account.AccountNumber))
{
returnList.Add(account);
}
}
}
return returnList;
}
public AccountModel MapAccountFromXml(XmlNode node) {
if (!IsValidAccount(node) {
return null;
}
// This performs a lot of XML manipulation getting nodes based on attributes
// and mapping them to the various properties of the AccountModel. It's messy
// and I didn't want it inline with the other code.
return populatedAccountModel;
{
public bool IsValidAccount(XmlNode node)
{
var taxSelectValue = node.SelectSingleNode("//FORMAT/Field[#taxSelect='1']").First().Value;
var accountStatus = // similar to first line in that it gets a single node using a specific XPath
var maturityDate = // similar to first line in that it gets a single node using a specific XPath
var maturityValue = // similar to first line in that it gets a single node using a specific XPath
return taxSelectValue != string.Empty && taxSelectValue != "0" && (accountStatusValue != "CL" || (maturityDate.Year >= DateTime.Now.AddYears(-1).Year));
}
}
What I want to do is test my GetAccounts() method. I can stub out the IExternalWebServiceProxy call and return fake XML, but I have internal calls happening in my service since my GetAccounts() method calls MapAccountFromXml() which in turn calls IsValidAccount().
Perhaps the solution is to not worry about breaking out the long and involved MapAccountFromXml() and IsValidAccount() code and just put them inline into the GetAccount() call, but I would rather leave them broken out for code readability.
I have my Moles assembly created, and know I can create a stub version of my class like this
var stubWebService = SIExternalWebServiceProxy {
GetAllCustomerAccounts = delegate {
return SomeHelper.GetFakeXmlDocument();
}
}
var stubAccountService = new SAccountService() { callsBase = true; }
My problem is I don't know how to then override the internal calls to MapAccountFromXml and IsValidAccount and I don't want my Unit Test to be testing thos methods, I'd like to isolate GetAccounts for the test. I read somewhere the methods need to be virtual to be overriden in a partial stub, but could not find anything that then showed how to create a stub that overrides a few methods while calling the base for the one I want to test.
Peer put me on the right track, thank you.
It turned out that what I was looking for is called Detours in Moles. Rather than stub an interface using
var stubAccountService = new SIAccountService();
what I needed to do was create an instance of my AccountService and then detour all calls to the methods I wanted to mock, like this
var accountService = new AccountService();
MAccountService.AllInstances.MapAccountFromXmlXmlNode = delegate {
return new AccountModel();
};
The MAccountService is provided by Moles when you Mole your assembly. The only missing piece to this is that for this to work you need to add the following attribute to your test method:
[HostType("Moles")]
This worked for me locally, but in the end I had trouble getting TFS to do automated builds
UPDATE
I just stumbled on another way of doing this, while looking at Rhino Mocks. If the methods in the class being mocked are virtual then you can override them in the mock, like this:
var accountService = new SAccountService();
accountService.MapAccountFromXmlXmlNode = delegate
{
return new AccountModel();
}
Now I can call
accountService.GetMemberAccounts();
and when accountService makes its call to MapAccountFromXml it will be caught by the stub and processed as I deem necessary. No messing with HostType and it works like a charm.
To test methods in you class in issolation you do this with moles by making a mole for the IsValidAccount and MapAccountFromXml methods. Or make a stub implementation with stubs where you let the stub call the orriginal methode using base. Or what I think is a nicer solution, make a test class which overrides the methods you do want to stub (this is the same what a stub would do, except you see all what is happening in your own code):
public class TestHelperAccountService : AccountService {
public override AccountModel MapAccountFromXml(XmlNode node) {
return new AccountModel(){
//Accountmodelstub
};
{
public override bool IsValidAccount(XmlNode node)
{
return true;
}
}
This way you can do your test for the GetAccount method on your TestHelperAccountService class where you GetAccount method runs in full issolation. You can do the same for the methods like MapAccountFromXml to test them seperatly.

Moq tests using ExpectSet() with It.Is<T>() aren't behaving as... expected

I've isolated the behaviour into the following test case. I'd be grateful to anyone who can tell me how to expect/verify a property set for a List<T> property - it appears there's something going on inside It.Is<T>(predicate) that isn't making a whole lot of sense to me right now. Sample code will run as a console app from VS2008 - you'll need to add a reference to Moq 2.6 (I'm on 2.6.1014.1) - please try uncommenting the different ExpectSet statements to see what's happening...
using System;
using Moq;
using System.Collections.Generic;
namespace MoqDemo {
public interface IView {
List<string> Names { get; set; }
}
public class Controller {
private IView view;
public Controller(IView view) {
this.view = view;
}
public void PopulateView() {
List<string> names = new List<string>() { "Hugh", "Pugh", "Barney McGrew" };
view.Names = names;
}
public class MyApp {
public static void Main() {
Mock<IView> mockView = new Mock<IView>();
// This works - and the expectation is verifiable.
mockView.ExpectSet(mv => mv.Names);
// None of the following can be verified.
// mockView.ExpectSet(mv => mv.Names, It.Is<Object>(o => o != null));
// mockView.ExpectSet(mv => mv.Names, It.Is<List<string>>(names => names.Count == 3));
// mockView.ExpectSet(mv => mv.Names, It.IsAny<IList<String>>());
Controller controller = new Controller(mockView.Object);
controller.PopulateView();
try {
mockView.VerifyAll();
Console.WriteLine("Verified OK!");
} catch (MockException ex) {
Console.WriteLine("Verification failed!");
Console.WriteLine(ex.Message);
}
Console.ReadKey(false);
}
}
}
}
I'm not using the very latest version of Moq, so I don't have an overload of ExpectSet that takes two parameters, but I've had some success with this pattern:
mockView.ExpectSet(mv => mv.Names).Callback(n => Assert.That(n != null));
The Assert (from NUnit) call in the callback will throw an exception if the value assigned to .Names doesn't match the predicate. It does make it hard to trace when a test fails, though. I agree that the ability to pass an It.Is or It.IsAny as the second parameter would be handy.
The second parameter of ExpectSet() is the value you're expecting. You can't use It.Is<T> in this case as there's no overload that takes a predicate - though it would be nice ;) Here's a (simplified) excerpt from your sample, illustrating the use of a value:
var mockView = new Mock<IView>();
var list = new List<string> { "Hugh", "Pugh", "Barney McGrew" };
mockView.ExpectSet(mv => mv.Names, list);
mockView.Object.Names = list;
Hope that helps.
Edit: fixed typo.
BTW, It.Is is not supported on ExpectSet. Your code compiles just because they are regular method invocations when used as values (as opposed to expressions), whereas when used in an Expect expression they are pre-processed by Moq and given specific meaning (rather than the null/default value that all It.Is members actually return).
You could use the stub behavior on the given property (mockView.Stub(mv => mv.Names)) and later assert directly for its value after execution.
Moq doesn't provide an overload receiving It.IsAny as it's effectively the same as calling ExpectSet without passing an expected value ;)