I have this case that I want to run PHPUnit test and check behaviour of current testing class as follows:
public function it_allows_to_add_items()
{
// Create prophesies
$managerProphecy = $this->getProphet(ListingManager::class);
$listingItemProphecy = $this->getProphet(ListingItemInterface::class);
$listing = factory(\App\Misc\Listings\Listing::class)->create();
$manager = new ListingManager($listing);
$item = factory(\App\Misc\Listings\ListingItem::class)->make(['listing_id' => null]);
$item2 = factory(\App\Misc\Listings\ListingItem::class)->make(['listing_id' => null]);
$manager->addItem($item);
$managerProphecy->validate($listingItemProphecy)->shouldBeCalledTimes(2);
$manager->addItem($item2);
$this->assertTrue(true);
}
is that even possible ?
Of course I'm getting
1) GenericListingManagerTest::it_allows_to_add_items
Some predictions failed:
Double\App\Misc\Listings\ListingManager\P2:
Expected exactly 2 calls that match:
Double\App\Misc\Listings\ListingManager\P2->validate(exact(Double\ListingItemInterface\P1:00000000058d2b7a00007feda4ff3b5f Object (
'objectProphecy' => Prophecy\Prophecy\ObjectProphecy Object (*Prophecy*)
)))
but none were made.
I think your way to approach this test is a bit off. If I understand correctly you want to verify that addItem(object $item) works properly, i.e. the manager contains the item and the item is the same you added. For this you should not need prophecies and in fact your test does not actually use the prophecies you created. Depending on what your Manager looks like you could write something like this:
function test_manager_add_items_stores_item_and_increases_count()
{
$manager = new ListingManager(); // (2)
$item = new ListingIem(); // (3)
$initialCount = $manager->countItems(); // (1)
$manager->addItem($item);
$this->assertEquals($initialCount + 1, $manager->countItems());
// Assuming offset equals (item count - 1) just like in a numeric array
$this->assertSame($item, $manager->getItemAtOffset($initialCount));
}
(1) Assuming your manager has a count()-method you can check before and after whether the count increased by the number of added items.
(2) We want to test the real manager - that's why we don't need a mock created by prophecy here - and we can use a real item because it's just a value.
(3) I'm not sure why you have a ListingItemInterface. Are there really different implementations of ListingItem and if so, do you really want a generic ListingManager that possibly contains all of them or do you need a more specific one to make sure that each Manager contains only it's specific kind of item? This really depends on your use case, but it looks like you might violate the I (Interface Segregation Principle) or L (Liskov Substitution Principle) in SOLID.
Depending on your use case you might want to add real items, e.g. 2 different types to make clear that it's intended that you can put 2 different implementations of the interface in there or you can do it like above and just add a ListingItem and verify that each item in the manager implements the interface - I leave finding the assertion for that to you ;). Of course you can use your factory to create the item as well. The important thing is that we test with assertSame() whether the managed object and the one we created initially are the same, meaning reference the exact same object.
You could add additional tests if you want to ensure additional behaviour, such as restricting the kind of items you can put in the manager or how it behaves when you put an invalid object in there.
The important thing is, that you want to test the actual behaviour of the Manager and that's why you don't want to use a mock for it. You could use a mock for the ListingItemInterface should you really require it. In that case the test should probably look something like this:
function test_manager_add_items_stores_item_and_increases_count()
{
$manager = new ListingManager();
$dummyItem = $this->prophecy(ListingIemInterface::class);
$initialCount = $manager->countItems();
$manager->addItem($dummyItem->reveal());
$this->assertEquals($initialCount + 1, $manager->countItems());
$this->assertSame($dummyItem, $manager->getItemAtOffset($initialCount));
}
edit: If addItem checks the validation which you want to skip, e.g. because the empty item you provide is not valid and you don't care. You can use PHPUnit's own mock framework to partially mock the manager like this:
$item = new ListingItem();
$managerMock = $this->getMockBuilder(ListManager::class)
->setMethods(['validate'])
->getMock();
$managerMock
->expects($this->exactly(2))
->method('validate')
->with($this-> identicalTo($item))
->willReturn(true);
$managerMock->addItem($item);
$managerMock->addItem($item);
You don't have to assert anything at the end, because expects() is already asserting something. Your Manager will work normally, except for validate(), meaning you will run the code in addItem() and if in there validate is called (once per item) the test will pass.
Related
I have a function that takes a number of values, creates a new model, and then saves this in storage via a PersistentMap.
I would like to test that the item is successfully saved in storage. This is how I'm going about it:
it("saves a new item to storage", () => {
VMContext.setCurrent_account_id("test_account_id");
contract.createMyPersistantMapItem(
"value 1",
"value 2",
"value 3"
);
expect(storage.hasKey("myPersistantMap::test_account_id")).toBeTruthy();
});
However the test fails with the following:
[Actual]: false
[Expected]: Truthy
[Stack]: RuntimeError: unreachable
at node_modules/#as-pect/assembly/assembly/internal/assert/assert (wasm-function[53]:0xd71)
at start:src/simple/__tests__/index.unit.spec~anonymous|0~anonymous|0~anonymous|0 (wasm-function[130]:0x2a84)
at node_modules/#as-pect/assembly/assembly/internal/call/__call (wasm-function[134]:0x2aac)
Am I going about this the wrong way?
Also I would like to test the values in the item are correct. In the todos example the created todo is returned from the function that creates it, and then this returned value is tested. Is this the best way of doing things to make testing easier?
EDIT
This is the createMyPersistantMapItem function - edited a bit to make things clearer:
export function createMyPersistantMapItem(
blah1: string,
blah2: string,
blah3: string,
): void {
const accountId = context.sender;
assert(
!storage.hasKey("myPersistantMap::" + accountId),
"Item already exists"
);
const newPersistantMapItem = new PersistantMapItem(
blah1,
blah2,
blah3
);
myPersistantMap.set(accountId, newPersistantMapItem);
}
About the first question:
Does myPersistentMap use the "myPersistantMap" prefix when initialized? Does PersistantMapItem use the #nearBingden annotation on the class?
Also, in your test, I think you should use
VMContext.setSigner_account_id("test_account_id")
//instead of
VMContext.setCurrent_account_id("test_account_id")
Because you are using context.sender when you call createMyPersistantMapItem
About the second question:
In the todos example the created todo is returned from the function that creates it, and then this returned value is tested. Is this the best way of doing things to make testing easier?
This question is primarily opinion based, so I can only answer for myself. Testing the returned value is completely fine. In a smart contract however, I would probably test if the value is actually stored on the contract. And I think they are doing that in the TODO example. They just use the ID of the generated TODO to do a query on the smart contract.
const a = Todo.insert("Drink water");
// They use the id of the todo (a) to check if it was actually stored, and is in fact the same object. I think this is fine.
expect(getById(a.id)).toStrictEqual(a);
I am trying to change the volume using Line.kr but I get this error: ERROR: can't set a control to a UGen
Here is the code:
a = {arg freq=440, vol=0; SinOsc.ar(freq)*vol}.play
a.set(\vol,Line.kr(0,1.0,3))
Any ideas?
This is actually such a basic issue/topic that a more elaborate answer is perhaps warranted. Basically, if you need/want "total flexibility" in what that \vol envelope is, you have to read it from a (server-side) bus or use one of the many client-side wrapper tricks that hide that (bus) plumbing under some syntactic sugar. A typical example of the latter would be JITLib. An example using the latter:
a = Ndef(\a, {arg freq=440, vol=0; SinOsc.ar(freq)*vol}).play;
a.set(\vol, Ndef(\v, { Line.kr(0,1.0,3) }))
If you now do a.edit you'll see somthing like
Without using that JITLib sugar, you'd have allocate and map a bus yourself, such as in:
a = {arg freq=440, vol=0; SinOsc.ar(freq)*vol}.play;
b = Bus.control(s, 1); // "s" is the default-bound server variable
a.map(\vol, b);
c = { Out.kr(b, Line.kr(0,1.0,3);) }.play;
With JITlib you can just set all over as it has "smarts" to detect the argument type, but with the basic SC you need to distinguish between mapping and setting... although you can also set something to a c-led bus-number string to achieve the same effect (map basically does that for you), i.e. the penultimate line above can be a.set(\vol, b.asMap); Just b.asMap evaluates to something like e.g. "c1", meaning control bus 1. (Audio busses use "a" prefixes instead, as you might expect.)
This bit may be somewhat more confusing, but keeping in mind that a and ~a are different types of variables (more or less function stack vs environment stack), the Ndef keys (first Ndef arguments) can be used "directly" in "shortcut" ~variables provided by the ProxySpace as in
p = ProxySpace.push(s);
~a = {arg freq=440, vol=0; SinOsc.ar(freq)*vol};
~a.play; // play the NodeProxy, not the Function (Synth) directly
~a.set(\vol, ~v); // ~v is a NodeProxy.nil(localhost, nil) due to ProxySpace
~v = { Line.kr(0,1.0,3) };
Under the hood this last example practically auto-issues Ndefs, i.e the 2nd line does the same as Ndef(\a ..., so you don't have to type Ndefs explicitly anymore. The way this works is that ProxySpace replaces the currentEnvironment (where ~variables live) with one in which put, which is triggered by assignments to ~variables, is now creating or modifying Ndefs and at is accessing them, e.g. if you evaluate currentEnvironment now it shows something like
ProxySpace ( ~a - ar(1) ~v - kr(1) )
(To get back to your prior environment issue a p.pop now.)
You can't use UGen to set some arg of a SynthDef, but you can set the arguments of Line.kr:
a = {arg freq=440, vol=0; SinOsc.ar(freq)*Line.kr(atk,sus,rel)}.play
a.set(\atk,0,\sus,1,\rel,0)
please note that with Line.kr you can't restart the envelope.
For a more specific control please see the EnvGen UGen:
http://doc.sccode.org/Classes/EnvGen.html
I have the following UnitTest:
[TestMethod]
public void NewGamesHaveDifferentSecretCodesTothePreviousGame()
{
var theGame = new BullsAndCows();
List<int> firstCode = new List<int>(theGame.SecretCode);
theGame.NewGame();
List<int> secondCode = new List<int>(theGame.SecretCode);
theGame.NewGame();
List<int> thirdCode = new List<int>(theGame.SecretCode);
CollectionAssert.AreNotEqual(firstCode, secondCode);
CollectionAssert.AreNotEqual(secondCode, thirdCode);
}
When I run it in Debug mode, my code passes the test, but when I run the test as normal (run mode) it does not pass. The exception thrown is:
CollectionAssert.AreNotEqual failed. (Both collection contain same elements).
Here is my code:
// constructor
public BullsAndCows()
{
Gueses = new List<Guess>();
SecretCode = generateRequiredSecretCode();
previousCodes = new Dictionary<int, List<int>>();
}
public void NewGame()
{
var theCode = generateRequiredSecretCode();
if (previousCodes.Count != 0)
{
if(!isPreviouslySeen(theCode))
{
SecretCode = theCode;
previousCodes.Add(previousCodes.Last().Key + 1, SecretCode);
}
}
else
{
SecretCode = theCode;
previousCodes.Add(0, theCode);
}
}
previousCodes is a property on the class, and its Data type is Dictionary key integer, value List of integers. SecretCode is also a property on the class, and its Data type is a List of integers
If I were to make a guess, I would say the reason is the NewGame() method is called again, whilst the first call hasn't really finished what it needs to do. As you can see, there are other methods being called from within the NewGame() method (e.g. generateRequiredSecretCode()).
When running in Debug mode, the slow pace of my pressing F10 gives sufficient time for processes to end.
But I am not really sure how to fix that, assuming I am right in my identification of the cause.
What happens to SecretCode when generateRequiredSecretCode generates a duplicate? It appears to be unhandled.
One possibility is that you are getting a duplicate, so SecretCode remain the same as its previous value. How does the generator work?
Also, you didn't show how the BullsAndCows constructor is initializing SecretCode? Is it calling NewGame?
I doubt the speed of keypresses has anything to do with it, since your test method calls the functions in turn without waiting for input. And unless generateReq... is spawning a thread, it will complete whatever it is doing before it returns.
--after update--
I see 2 bugs.
1) The very first SecretCode generated in the constructor is not added to the list of previousCodes. So the duplicate checking won't catch if the 2nd game has the same code.
2) after previousCodes is populated, you don't handle the case where you generate a duplicate. a duplicate is previouslySeen, so you don't add it to the previousCodes list, but you don't update SecretCode either, so it keeps the old value.
I'm not exactly sure why this is only showing up in release mode - but it could be a difference in the way debug mode handles the random number generator. See How to randomize in WPF. Release mode is faster, so it uses the same timestamp as seed, so it does in fact generate exactly the same sequence of digits.
If that's the case, you can fix it by making random a class property instead of creating a new one for each call to generator.
Consider the following:
IEnumerable<ShellTile> pinnedtiles = ShellTile.ActiveTiles;
Console.WriteLine(pinnedtiles.Count());
Console.WriteLine(pinnedtiles.Count());
Assuming you have more than 0 ActiveTiles, the first call to Count() will return the correct value, but the second call will return 0.
If you dont set ShellTile.ActiveTiles to a local variable, it works fine. I assume this is because ActiveTiles is actually an instance of the internal class ShellTileEnumerator and for some reason, when accessed via the IEnumerable interface, it is acting like a forward-only enumerator. Seems like a likely 'gotcha', or am I misunderstanding something?
Yes you are right
MessageBox.Show(ShellTile.ActiveTiles.Count().ToString());
MessageBox.Show(ShellTile.ActiveTiles.Count().ToString());
The above one will work but not when you assign to IEnumeable .... :)
Another easy way is to assign it toa List instead of IEnumerable . This works too
List<ShellTile> pinnedtiles = ShellTile.ActiveTiles.ToList(); ;
MessageBox.Show(pinnedtiles.Count().ToString());
MessageBox.Show(pinnedtiles.Count().ToString());
Sorry if this is basic but I was trying to pick up on .Net 3.5.
Question: Is there anything great about Func<> and it's 5 overloads? From the looks of it, I can still create a similar delgate on my own say, MyFunc<> with the exact 5 overloads and even more.
eg: public delegate TResult MyFunc<TResult>() and a combo of various overloads...
The thought came up as I was trying to understand Func<> delegates and hit upon the following scenario:
Func<int,int> myDelegate = (y) => IsComposite(10);
This implies a delegate with one parameter of type int and a return type of type int. There are five variations (if you look at the overloads through intellisense). So I am guessing that we can have a delegate with no return type?
So am I justified in saying that Func<> is nothing great and just an example in the .Net framework that we can use and if needed, create custom "func<>" delegates to suit our own needs?
Thanks,
The greatness lies in establishing shared language for better communication.
Instead of defining your own delegate types for the same thing (delegate explosion), use the ones provided by the framework. Anyone reading your code instantly grasps what you are trying to accomplish.. minimizes the time to 'what is this piece of code actually doing?'
So as soon as I see a
Action = some method that just does something and returns no output
Comparison = some method that compares two objects of the same type and returns an int to indicate order
Converter = transforms Obj A into equivalent Obj B
EventHandler = response/handler to an event raised by some object given some input in the form of an event argument
Func = some method that takes some parameters, computes something and returns a result
Predicate = evaluate input object against some criteria and return pass/fail status as bool
I don't have to dig deeper than that unless it is my immediate area of concern. So if you feel the delegate you need fits one of these needs, use them before rolling your own.
Disclaimer: Personally I like this move by the language designers.
Counter-argument : Sometimes defining your delegate may help communicate intent better. e.g. System.Threading.ThreadStart over System.Action. So it’s a judgment call in the end.
The Func family of delegates (and their return-type-less cousins, Action) are not any greater than anything else you'd find in the .NET framework. They're just there for re-use so you don't have to redefine them. They have type parameters to keep things generic. E.g., a Func<T0,bool> is the same as a System.Predicate<T> delegate. They were originally designed for LINQ.
You should be able to just use the built-in Func delegate for any value-returning method that accepts up to 4 arguments instead of defining your own delegate for such a purpose unless you want the name to reflect your intention, which is cool.
Cases where you would absolutely need to define your delegate types include methods that accept more than 4 arguments, methods with out, ref, or params parameters, or recursive method signatures (e.g., delegate Foo Foo(Foo f)).
In addition to Marxidad's correct answer:
It's worth being aware of Func's related family, the Action delegates. Again, these are types overloaded by the number of type parameters, but declared to return void.
If you want to use Func/Action in a .NET 2.0 project but with a simple route to upgrading later on, you can cut and paste the declarations from my version comparison page. If you declare them in the System namespace then you'll be able to upgrade just by removing the declarations later - but then you won't be able to (easily) build the same code in .NET 3.5 without removing the declarations.
Decoupling dependencies and unholy tie-ups is one singular thing that makes it great. Everything else one can debate and claim to be doable in some home-grown way.
I've been refactoring slightly more complex system with an old and heavy lib and got blocked on not being able to break compile time dependency - because of the named delegate lurking on "the other side". All assembly loading and reflection didn't help - compiler would refuse to just cast a delegate() {...} to object and whatever you do to pacify it would fail on the other side.
Delegate type comparison which is structural at compile time turns nominal after that (loading, invoking). That may seem OK while you are thinking in terms of "my darling lib is going to be used forever and by everyone" but it doesn't scale to even slightly more complex systems. Fun<> templates bring a degree of structural equivalence back into the world of nominal typing . That's the aspect you can't achieve by rolling out your own.
Example - converting:
class Session (
public delegate string CleanBody(); // tying you up and you don't see it :-)
public static void Execute(string name, string q, CleanBody body) ...
to:
public static void Execute(string name, string q, Func<string> body)
Allows completely independent code to do reflection invocation like:
Type type = Type.GetType("Bla.Session, FooSessionDll", true);
MethodInfo methodInfo = type.GetMethod("Execute");
Func<string> d = delegate() { .....} // see Ma - no tie-ups :-)
Object [] params = { "foo", "bar", d};
methodInfo.Invoke("Trial Execution :-)", params);
Existing code doesn't notice the difference, new code doesn't get dependence - peace on Earth :-)
One thing I like about delegates is that they let me declare methods within methods like so, this is handy when you want to reuse a piece of code but you only need it within that method. Since the purpose here is to limit the scope as much as possible Func<> comes in handy.
For example:
string FormatName(string pFirstName, string pLastName) {
Func<string, string> MakeFirstUpper = (pText) => {
return pText.Substring(0,1).ToUpper() + pText.Substring(1);
};
return MakeFirstUpper(pFirstName) + " " + MakeFirstUpper(pLastName);
}
It's even easier and more handy when you can use inference, which you can if you create a helper function like so:
Func<T, TReturn> Lambda<T, TReturn>(Func<T, TReturn> pFunc) {
return pFunc;
}
Now I can rewrite my function without the Func<>:
string FormatName(string pFirstName, string pLastName) {
var MakeFirstUpper = Lambda((string pText) => {
return pText.Substring(0,1).ToUpper() + pText.Substring(1);
});
return MakeFirstUpper(pFirstName) + " " + MakeFirstUpper(pLastName);
}
Here's the code to test the method:
Console.WriteLine(FormatName("luis", "perez"));
Though it is an old thread I had to add that func<> and action<> also help us use covariance and contra variance.
http://msdn.microsoft.com/en-us/library/dd465122.aspx