I am trying to mock out some code that returns information by writing to one of the references passed to the function as a parameter. Is there a good way to mock this behavior such that I can have the test code determine what value is written to that variable?
I did a little research and it turns out that GMock has a couple of nice options. From the Google Mock Cheat Sheet
SetArgReferee<N>(value)
SetArgPointee<N>(value)
"Assign value to the variable referenced by the N-th (0-based) argument" and "Assign value to the variable pointed by the N-th (0-based) argument" respectively.
You have quite a few options.
SetArgReferee(value) and SetArgPointee(value), as Daniel pointed out in 2015.
Then there's SetArrayArgument(first, last) for arrays.
Or you can use Invoke capabilities to invoke your own functions and do what you want: Invoke, InvokeWithoutArgs, InvokeWithoutArgs, InvokeArgument.
Read their descriptions in the Side Effects and Invoke sections on the Googlemock's cheat sheet page.
Related
I'm trying to write a google-test utility function which performs some setup steps base on it's input arguments and finally compares the contents of two containers irrespective of order. I would then like to return a ::testing::AssertionResult from this function based on whether the container contents are equal.
For the comparison itself I would like to use functionalities provided by google-mock in order to avoid errors in my own test-code and reduce developement overhead. Something like the following would work:
EXPECT_THAT(actual_container,
testing::UnorderedElementsAreArray(expected_container))
<< "Container content equal.";
The trouble with this is that I'm not sure if it is even possible to
obtain an AssertionResult which can be returned from a function in a similar manner.
Does anyone have a solution to this or a suggestion for an alternative approach?
I am trying to use Moq for testing a manager that has many CRUD operations defined in it. One of the methods is taking an integer parameter and returning a list based on conditions. I want to assert if the list does have a count greater than 0. How to do this using Moq? This is my attempt, guidance needed.
// set up the mock method making sure integer is passed and list is returned
var mockAssessmentManager = new Mock<IAssessmentManager>();
mockAssessmentManager.Setup(x => x.GetAssessmentElementUserRowByAssessment(It.IsAny<int>()))
.Returns(new List<AssessmentElementUser>());
// Assert.IsTrue(myReturnList.Count > 0); //want to achieve some like this.
Assert.IsTrue(mockAssessmentManager);
Am I doing it the right way? How to assert my collection of List<T> to check if count > 0?
The title "To check if List<T> returns a collection" makes no sense because List<T> is a type not a method, so it doesn't return anything it is something. Read How to ask to see how important the title is.
You say you are testing a manager, and the example shows code which is mocking a manager. But if you are mocking the manager, you aren't testing it, you should be testing the thing which uses the manager. I'm going to assume that to be the case.
Given that you are setting up your mock to return a collection when the manager is called, you can use Verify to check that that happened to your mock (the syntax is very similar to Setup). But quite often you don't need to, since the return value from code under test is often driven by the value returned by the dependency.
For example, if the return value from the code under test should be the value that the manager returned to it (which is the collection you return in the Setup), asserting that the value returned is reference equals the same as your mock returned is the solution. (There is no other way that assert could pass unless the method that was setup was called.)
There certainly doesn't seem to be any value in asserting anything about a collection which you have set up as part of your test.
Bonus tip: you haven't tagged which testing framework you're using but Assert.IsTrue(myReturnList.Count > 0); is a bad way is asserting, since if the assert fails the message is always "expected true but was false". Whereas Assert.That(myReturnList, Has.Count.GreaterThan(0)); (I'm assuming NUnit) will give much better information if it fails.
Another tip, I need to offer a caution about using It.IsAny. Take a look at this question (which is about Verify, but the syntax is very similar to Setup, and the concern about It.IsAny is the same). Read the non accepted answer and all the comments, then the accepted answer.
I am trying to understand the programming of Siemens scanner using C++ and given that my C++ skills are limited, I am having problems in understanding many parts of the code provided by the vendor.
Problem 1
For instance, the code uses reference (rMrProt) to object MrProt and notations (such as the use of use of (). and ()[].) are very confusing to me.
For instance:
ImageSamples = rMrProt.kSpace().baseResolution()
ImageSize = rMrProt.sliceSeries()[0].readoutFOV()
Some explanation of these statements would be appreciated.
All information regarding object MrProt are in “MrProt.h”, “MrProt.dll”, “MrProt.lib”. All these files have been shared at:
https://docs.google.com/open?id=0B0Ah9soYnrlIYWZkNDU2M2EtYTNmNC00YTc5LTllMzItYzIyMWU4M2ZhY2Fi
Problem 2
Also, I have been trying to read MrProt.dll and MrProt.lib without any success. Only now, I came to know of dumpbin. Any help would be appreciated.
Problem 3
Another confusion that I have is related to some part of MrProt.h itself. There is a statement in MrProt.h:
class __IMP_EXP MrProt: public MrProtocolData::MrProtDataDelegate
{
typedef MrProtocolData::MrProtDataDelegate BasicImplementation;
public:
MrProt();
MrProt(const MrProt& rSource);
…
….
}
Here, __IMP_EXP, I guess that it’s some compiler specific stuff.. some decoration etc. But, I still have no idea what to make of this.
Problem 1.
rMrProt.sliceSeries()[0].readoutFOV()
means
Take rMrProt's sliceSeries member and call that. Apparently, it returns an array-like object, something that can be indexed.
From the result, take the first element ([0]). That's some kind of object.
On that element/object, call readoutFOV.
Problem 2. You're not really supposed to read binary files. There should be documentation with them.
1)
ImageSamples = rMrProt.kSpace().baseResolution()
This is just method chaining. You call the method kSpace() on rMrPrto which returns an object, and you call baseResolution() on that object.
2) Those are binary files. What would you expect to see? To read them you'd have to be an expert in asm or at least know some low-level concepts.
3) __IMP_EXP is a common type of directive that tells the compiler that the class is either exported or imported.
It expands to _declspec(dllimport) or _declspec(dllexport), depending on whether the definition of the class is in the current module or another module.
identifier() is a method/function call
identifier[i] returns the i'th element in an array.
identifier()[i] returns the i'th element of the array returned by identifier()
I can only help on problem 1:
if the return value of rMrProt.kSpace() is a struct. instead of saving it to a struct and then access it's member you can directly access a member of his with rMrProt.kSpace().MemberName
same for rMrProt.sliceSeries() which I guess is returning an array. so rMrProt.sliceSeries()[0] will access the first value in the returning array.
I'm having a bit of difficulty passing a reference type between webservices.
My set up is as follows.
I have a console application that references two web-services:
WebServiceOne
WebServiceTwo
WebServiceOne declares the details of a class I am using in my console application...let's call it MyClass.
My console application calls WebServiceOne to retrieve a list of MyClass.
It then sends each MyClass off to WebServiceTwo for processing.
Within in the project that holds WebServiceTwo, there is a reference to WebServiceOne so that I can have the declaration of MyClass.
The trouble I'm having is that, when I compile, it can't seem to determine that the MyClass passed from the console application is the same as the MyClass declared in WebServiceOne referenced in WebServiceTwo.
I basically get an error saying Console.WebServiceOne.MyClass is not the same as MyProject.WebServiceOne.MyClass.
Does anyone know if doing this is possible? Perhaps I'm referencing WebServiceOne incorrectly? Any idea what I might be doing wrong?
My only other option is to pass each of the properties of the reference type directly to WebServiceTwo as value types...but I'd like to avoid that since I'd end up passing 10-15 parameters.
Any help would be appreciated!
I had a chat with one of the more senior guys at my work and they proposed the following solution that has worked out well for me.
The solution was to use a Data Transfer Object and remove the reference to WebServiceOne in WebServiceTwo.
Basically, in WebServiceTwo I defined a representation of all the value type fields needed as BenefitDTO. This effectively allows me to package up all the fields into one object so I don't have to pass each of them as parameters in a method.
So for the moment, that seems to be the best solution...since it works and achieves my goal.
It's likely that I didn't explain my question very well...which explains why no one was able to help...
But thanks anyway! :-)
Move the types to a separate assembly and ensure that both services use this. In the web service reference there is probably some autogenerated code called Reference.cs. Alter this to use your types.
Edit: To reflect comments
In that case take the reference.cs from that web service you cannot control use it as the shared type.
Your error message explains the problem. The proxy class on the client side is not the same type as the original class on the server side, and never will be. Whether it's a reference type or a value type is irrelevant to how it works.
I don't quite understand what your exact problem is, but here are a few guesses:
If you are trying to compare two objects for equality, then you will have to write your own compare function that compares the values of each significant property/field in turn.
If you are trying to copy an object from one service to the other, then you will have to write your own copy function that copies the values of each significant property/field in turn.
If you were using WCF, you would have the option of bypassing all this and just sharing one class definition between the client and both services.
Description for Assert.Equals() from the MSDN Documentation:
Do not use this method.
That's it, the full explanation. Uh.. ok, but then ... why is it there?
Is it a deprecated method from an earlier version of the framework? Something that's supposed to be used only by other Microsoft Assemblies?
It just makes me want to use it all the more knowing I'm not supposed to. ;-)
Does anyone know?
.Equals is inherited from object. It's listed as "Do not use this method" so users won't confuse it with the AreEqual method.
All objects in .NET derive from Object.
Object has a .Equals() method.
Apparently the .Equals() method for this particular object doesn't do anything useful, so the docs are warning you that it doesn't do anything useful.
It was changed in 2008 (Maybe SP1) to fail a test when called, so that people who were using it by accident were told they really shouldn't be using it.
Assert.Equals, just like its based class method Object.Equals, is perfectly useful for comparing objects. However, neither method is useful for stand-alone detection and reporting or errors in unit testing, since Object.Equals returns a boolean rather than throws if the values are not equal. This is a problem if used like this in a unit test:
Assert.Equals(42, ComputeMeaningOfLife());
Aside from the problem of this unit test possibly running too long :-), this test would silently succeed even if the Compute method provides the wrong result. The right method to use is Assert.AreEqual, which doesn't return anything, but throws an exception if the parameters aren't equal.
Assert.Equals was added so code like in the sample above doesn't fall back to Object.Equals and silently neuter the unit test. Instead, when called from a unit test, Assert.Equals always throws an exception reminding you not to use it.