I'm reading this page (I'm not using Amazon, just reading for golang education)
https://aws.amazon.com/blogs/developer/mocking-out-then-aws-sdk-for-go-for-unit-testing/
When I try it for myself, I get type errors.
type Queue struct {
Client ThirdPartyStruct
URL string
}
type mockedReceiveMsgs struct {
ThirdPartyStruct
Resp ValueIWantToMock
}
q := Queue{Client: mockedReceiveMsgs{}}
When I try to do the exact same thing, I get
cannot use mocked literal (type mockedReceiveMsgs) as type ThirdPartyStruct in field value
I feel like I'm copying the Amazon tutorial exactly. How come in there code, mockedReceiveMsgs can be used in place of ThirdPartyStruct?
The issue is not with mocking but with the fact that Queue structure includes ThirdPartyStruct by value (as a substructure), not as a pointer. And so does mockedReceiveMsgs. It just so happened that in Queue structure this substructure can be accessed by Client name and in mockedReceiveMsgs it is supposedly "anonymous" (but actually can be referred by ThirdPartyStruct name if required).
So, q := Queue{Client: mockedReceiveMsgs{}} actually tries to copy over mockedReceiveMsgs into Client and it obviously fails as it has extra bits, which don't fit into ThirdPartyStruct. You can make it compile by changing it to q := Queue{Client: mockedReceiveMsgs{}.ThirdPartyStruct} though I doubt this is what you want.
Note, that if you change Client ThirdPartyStruct to Client interface{} (in your original example) then it will compile as well. And this is most likely what you want. And it will also work with any interface type. Which is what #tkausl most likely was pointing out. The only tricky bit is pointer semantics vs value semantics when you're implementing your interface. It does back fire sometimes. See a quick example here
If ThirdPartyStruct is, as it's name implies, a struct type as opposed to an interface type, then you cannot mock it, it is just not possible in Go. If you read your example article carefully and follow the link that shows the definition of SQSAPI you'll see that it is an interface type.
type SQSAPIinterface{
To make your code "mockable" you need to use an interface type for the Client field. Here's an example that is more true to the aws one: https://play.golang.org/p/puhhgmFCUC4
Related
While doing a game engine that uses .lua files in order to read parameter values, I got stuck when I had to read these values and assign them to the parameters of each component in C++. I tried to investigate the way Unity does it, but I didn't find it (and I'm starting to doubt that Unity has to do it at all).
I want the parameters to be initialized automatically, without the user having to do the process of
myComponentParameter = readFromLuaFile("myParameterName")
for each one of the parameters.
My initial idea is to use the std::variant type, and storing an array of variants in order to read them automatically. My problems with this are:
First of all, I don't know how to know the type that std::variant is storing at the moment (tried with std::variant::type, but it didn't work for the template), in order to cast from the untyped .lua value to the C++ value. For reference, my component initialization looks like this:
bool init(luabridge::LuaRef parameterTable)
{
myIntParameter = readVariable<int>(parameterTable, "myIntParameter");
myStringParameter = readVariable<std::string>(parameterTable, "myStringParameter");
return true;
}
(readVariable function is already written in this question, in case you're curious)
The second problem is that the user would have to write std::get(myIntParameter); whenever they want to access to the value stored by the variant, and that sounds like something worse than making the user read the parameter value.
The third problem is that I can't create an array of std::variant<any type>, which is what I would like to do in order to automatically initialize the parameters.
Is there any good solution for this kind of situation where I want the init function to not be necessary, and the user doesn't need to manually set up the parameter values?
Thanks in advance.
Let's expand my comment. In a nutshell, you need to get from
"I have some things entered by the user in some file"
to:
"the client code can read the value without std::get"
…which roughly translates to:
"input validation was done, and values are ready for direct use."
…which implies you do not store your variables in variants.
In the end it is a design question. One module somewhere must have the knowledge of which variable names exist, and the type of each, and the valid values.
The input of that module will be unverified values.
The output of the module will probably be some regular c++ struct.
And the body of that module will likely have a bunch of those:
config.foo = readVariable<int>("foo");
config.bar = readVariable<std::string>("bar");
// you also want to validate values there - all ints may not be valid values for foo,
// maybe bar must follow some specific rules, etc
assuming somewhere else it was defined as:
struct Configuration {
int fooVariable;
std::string bar;
};
Where that module lives depends on your application. If all expected types are known, there is no reason to ever use a variant, just parse right away.
You would read to variants if some things do not make sense until later. For instance if you want to read configuration values that will be used by plugins, so you cannot make sense of them yet.
(actually even then simply re-parsing the file later, or just saving values as text for later parsing would work)
For an class in SwiftUI to conform to BindableObject, it has to have a Publisher, usually didChange, which in all of the SwiftUI documentation and videos I've seen so far, is a PassthroughSubject.
For example, if you have a class called TestObject, didChange might equal PassthroughSubject<TestObject, Never>(). I understand that the first type is the type of the data that the PassthroughSubject passes on, but what is Never? What is its purpose and are there any scenarios where the second type is not Never?
The second type provided to PassthroughSubject is the type used in case of failure.
final class PassthroughSubject<Output, Failure> where Failure : Error
The only requirement for this type is to conform to Error.
You can use an error type when the way you get your data can produce an error, like a network error for example.
The accepted answer does not address what Never is and why we may use it with a PassthroughSubject.
Never is defined as a enum with no cases. This means it can never be constructed. Sounds useless. However it can very useful to make sure functions behave as expected.
For example fatalError. fatalError will never return because it crashes the application. So you might be tempted to declare it as:
func fatalError() {}
However this would not be correct. The above function is actually returning an empty tuple (like all functions declared as above in swift). To be type correct we want to let the compiler know that if this function is called it will never return to the code that originally called it. Therefore we can use Never.
Never in PassthroughSubject
Sometimes we want Subjects that can never send errors. By declaring:
PassthroughSubject<TestObject, Never>()
you are saying that this subject will never fail with an error. So in our code we can't call the following because we can't construct a Never type to pass into the .failure:
subject.send(completion: .failure(<Nothing to construct here>))
For example: Let's say we had a timer and we wanted to publish events every 5 seconds. We could use a PassthroughSubject to send messages every 5 seconds to its subscribers. However we know it can't fail so to be clear to any consumers of our api that they don't need to worry about handling the failure case we can declare the PassthroughSubject with Never as the Error type.
Note:
The stream can still be terminated using the following:
subject.send(completion: .finished)
Following my reading of the article Programmers Are People Too by Ken Arnold, I have been trying to implement the idea of progressive disclosure in a minimal C++ API, to understand how it could be done at a larger scale.
Progressive disclosure refers to the idea of "splitting" an API into categories that will be disclosed to the user of an API only upon request. For example, an API can be split into two categories: a base category what is (accessible to the user by default) for methods which are often needed and easy to use and a extended category for expert level services.
I have found only one example on the web of such an implementation: the db4o library (in Java), but I do not really understand their strategy. For example, if we take a look at ObjectServer, it is declared as an interface, just like its extended class ExtObjectServer. Then an implementing ObjectServerImpl class, inheriting from both these interfaces is defined and all methods from both interfaces are implemented there.
This supposedly allows code such as:
public void test() throws IOException {
final String user = "hohohi";
final String password = "hohoho";
ObjectServer server = clientServerFixture().server();
server.grantAccess(user, password);
ObjectContainer con = openClient(user, password);
Assert.isNotNull(con);
con.close();
server.ext().revokeAccess(user); // How does this limit the scope to
// expert level methods only since it
// inherits from ObjectServer?
// ...
});
My knowledge of Java is not that good, but it seems my misunderstanding of how this work is at an higher level.
Thanks for your help!
Java and C++ are both statically typed, so what you can do with an object depends not so much on its actual dynamic type, but on the type through which you're accessing it.
In the example you've shown, you'll notice that the variable server is of type ObjectServer. This means that when going through server, you can only access ObjectServer methods. Even if the object happens to be of a type which has other methods (which is the case in your case and its ObjectServerImpl type), you have no way of directly accessing methods other than ObjectServer ones.
To access other methods, you need to get hold of the object through different type. This could be done with a cast, or with an explicit accessor such as your ext(). a.ext() returns a, but as a different type (ExtObjectServer), giving you access to different methods of a.
Your question also asks how is server.ext() limited to expert methods when ExtObjectServer extends ObjectServer. The answer is: it is not, but that is correct. It should not be limited like this. The goal is not to provide only the expert functions. If that was the case, then client code which needs to use both normal and expert functions would need to take two references to the object, just differently typed. There's no advantage to be gained from this.
The goal of progressive disclosure is to hide the expert stuff until it's explicitly requested. Once you ask for it, you've already seen the basic stuff, so why hide it from you?
As an example, a string that contains only a valid email address, as defined by some regex.
If a field of this type would be a part of a more complex data structure, or would be used as a function parameter, or used in any other context, the client code would be able to assume the field is a string containing a valid email address. Thus, no checks like "valid?" should be ever necessary, so approach of domaintypes would not work.
In Haskell this could be accomplished by a smart constructor (section 1.2) and in Java by ensuring the type is immutable (all setters private) and by adding a check in the constructor that throws a RuntimeException if the string used to create the type doesn't contain a valid email address.
If this is impossible in plain Clojure, I would like to see an example implementation in some well known extensions of the language, like Typed Clojure.
Ok, maybe, I understand now a question and I formulate in the comment my thoughts not really well. So I try to suggest an admissible solution to your question and then I try to explain some ideas I tried to tell in the comment.
1) There is a gen-class that generates compiled bytecode for a class and you can set constructor for the class there.
2) You can create a record with defrecord in some namespace that is private by convention in your project, then you
create another namespace with public api and define your factory function here. So the user of your public namespace will be able to call only public functions of your public namespace. (Of course, he can call also private ones, but with some another code)
3) You can just define a function like make-email that will return a map.
So you didn't specify your data structure anywhere.
4) You can just document your code where you will warn people to use the factory function for construction.
But! In Java if your code requires some interface, then it's user problem to give to your code the valid interface implementation. So if you write even a little bit general code in Java you already has lost the property of the valid email string. This stuff with interfaces is because Java is statically typed language.
Clojure is, in general, dynamically typed, so the user, in general, should be able to pass arbitrary data structure to arbitrary function without any type problems in compile time and it's his fault if he pass the wrong data. That makes, for example, this thing possible: You create a record and create a factory (constructor) function. And you expect a record to be passed in your code. But the user can pass a map with the same keys as your record fields names and the code will work.
So, in general, if you want the user of your code to be responsible for passing a required typed in dynamically typed language, then it cost nothing for user to be responsible for constructing it in a correct way that you provide to him.
Another solutions are: User just write tests. You can specify in your api functions :pre and :post conditions to check the structure. You can use typed clojure with the ideas I wrote above. And you can use some additional declarative libraries, like that was mentioned in the first comment of #Thumbnail.
P.S. I'm not a clojure professional, so I could easily miss some better solutions.
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.