just came across a problem.
I'm trying to make a wcf service unittest ready or better all code have to be tested with unittest.
Atm its not possible coze I've got a connection to a crm 2011 server that is used every time.
so i replaced it with a Interface. but i want to unittest the WCF like you use it.
now my idea is to make a public method and and give a fake connection.
now my question is would it be possible to invoke this method(example: ConnectionHandler), even if its not in the interface?
this would look like this:
public interface IWCF
{
[OperationContract]
bool method1();
[OperationContract]
bool method2();
}
public class WCF: IWCF
{
public bool method1(){
...
}
public bool method2(){
...
}
private connection connectionHandler;
public connection ConnectionHandler(Iconnection con){
if(con != null){
connectionHandler = con;
} else {
connectionHandler = takedefault;
}
}
}
Edit
ah i forgot to tell this: im actually have the security in mind, i don't want that anyone can pass a different connection to the server its for unittest purpose only.
It is possible to invoke this method, you can cast the interface to the concrete object. But that would compromise the calling code, which should not know the implementation details of your service.
I would reccomend in your sittuation to use the constrcutor injection so your service implemetation would look like this:
public interface IWCF
{
[OperationContract]
bool method1();
[OperationContract]
bool method2();
}
public class WCF: IWCF
{
private connection connectionHandler;
public WCF(Iconnection con)
{
if(con != null){
connectionHandler = con;
} else {
connectionHandler = takedefault;
}
}
public bool method1(){
...
}
public bool method2(){
...
}
}
In this case the client code will not know the details of the service implementation, if you use the constrcutor injection on the client as well
One of important features of any well designed piece of code is that you are explicit about the functionality that you expose to your clients. This becomes a key feature of service orientated applications, as you are exposing your functionality in a standardised way for external clients to consume.
Calling a method that is not part of the interface is bad in principle as you are now programming to the implementation and not the interface. Happily WCF knows this and will not let you a method that is not on the interface as it is not decorated with the OperationContract attribute.
With respect to your code - I am not sure exactly what it is you are trying to achieve - to have a client set (what I assume is) something like a database connection makes me a little uneasy (for a start this means your service is holding some state which goes against the Service statelessness principle). This does not mean that what you are doing is necessarily wrong, but you should find that you only rarely have to violate this in a well designed application.
That said, if you want to expose different areas of functionality to different clients the correct way to do this is by exposing endpoints on your service representing the different contracts:
[ServiceContract]
public interface IWCF
{
[OperationContract]
bool method1();
[OperationContract]
bool method2();
}
[ServiceContract]
public interface IConnectionWCF
{
[OperationContract]
bool SetConnection(string connection);
}
public class WCF : IWCF, IConnectionWCF
{
public bool method1()
{
...
}
public bool method2()
{
...
}
public bool SetConnection(string connection)
{
...
}
}
You also need to be mindful that everything the WCF service received must first be serialized by the client, sent over the wire, and deserialized on the server. You are very much dealing with concrete classes here - not abstractions. Passing an interface (such as Iconnection) as an argument to a service call does not really make any sense in a service-orientated environment.
With regards to unit testing - just remember that fundamentally the class WCF is just a plain old class. You can unit test this class in isolation of the fact that it is a WCF service. You shouldn't be setting up any of the service hosting functionality within your unit tests anyway - you want to check that the code that YOU write is correct - the WCF stack has already been tested by Microsoft.
EDIT
In response to your comment, as suggested here, you should used constructor injection to set the connection object when the class is instantiated. This then raises the question of how you gain control over the instantiation of the WCF service. You need to implement IInstanceProvider, or for a more detailed implementation see here. This way, when you service is hosted in WCF, you use IInstanceProvider, when you are testing you simply pass your fake connection object to the constructor.
EDIT
To clarify, a unit test for this class would resemble this:
[TestClass]
public class UnitTests
{
[TestMethod]
public void Test()
{
Iconnection connection = new FakeConnection();
WCF classUnderTest = new WCF(connection);
//Run test logic
}
}
Related
I want to test my Class, which calls the third Party Webservice. Is it possible to use FakeItEasy for this?
Wenn I try to Fake the Class from Reference.cs (auto generated), UnitTest started and doesn't come back.
Reference.cs(auto generated)
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public partial class ws_AccessoryClient : System.ServiceModel.ClientBase<AccessoryService.ws_Accessory>,
AccessoryService.ws_Accessory
{
public ws_AccessoryClient()
{
}
public ws_AccessoryClient(string endpointConfigurationName) :
base(endpointConfigurationName)
{
}
public AccessoryService.ResponseMessageOf_ListOf_SomeMethodInfo SomeMethod(
AccessoryService.RequestMessageOf_SomeMethod request)
{
return base.Channel.SomeMethod(request);
}
}
Test.cs
[Test]
public void DoBusinessLogicTryTest()
{
var accessoryProxy = A.Fake<ws_AccessoryClient>();
}
As has been mentioned you may not want to do what you are purposing for Unit Testing as this would cause more noise than is necessary for a Unit Test which could used mocked interfaces. However it is a valid approach for integration testing, this would allow you to test that your WCF wiring is working as you expect it. It also allows you to test your application as whole if you are adopting a more behaviour driven style of testing where you want to mock as little as possible.
I use this approach myself for spinning up fake endpoints using NSubstitute which is covered in my blog Hosting a Mock as a WCF service. The main things you need to do is spin up a ServiceHost, give it the endpoint address you want to use, set the context mode to single and provide the mock you want to use as the endpoint.
var serviceHost = new ServiceHost(mock, new[] { baseAddress });
serviceHost.Description.Behaviors
.Find<ServiceDebugBehavior>().IncludeExceptionDetailInFaults = true;
serviceHost.Description.Behaviors
.Find<ServiceBehaviorAttribute>().InstanceContextMode = InstanceContextMode.Single;
serviceHost.AddServiceEndpoint(typeof(TMock), new BasicHttpBinding(), endpointAddress);
One thing that I do in my testing is randomly choose the port that I host the endpoint on and inject the address into my application during testing. That way your tests will be able to run on other machines and build servers without clashing with other ports in use.
After looking at your example you might want to consider using the WCF ChannelFactory to create your client instead of using a concrete proxy client class. The ChannelFactory creates a proxy on the fly using the Interface you provide and allowing you to inject the proxy into its dependencies using the service interface. This would make unit testing easier and give you a more decoupled design.
You cannot (and why would you want to?).
If you want to verify that your class under test makes the call to the service, then wrap the service call in a class who's only job it is to call the service, and define it with an interface.
interface ICallTheService
{
void CallTheService();
}
class ServiceCaller : ICallTheService
{
void CallTheService()
{
// Call the service...
}
}
Then you can fake this class and verify that your class under test invokes the CallTheService operation.
// fake the service caller and pass it into your service
var serviceCaller = A.Fake<ICallTheService>();
// Verify invocation
A.CallTo(() => serviceCaller.CallTheService()).MustHaveHappened();
I want to test the logic in my class, depends on Response from
WCF-Service
This is where I think you're going wrong with separation of concerns. Your test is called DoBusinessLogicTryTest, yet it has a dependency on System.ServiceModel, which is an infrastructure concern. Your business logic should be testable without this dependency. If your class under test needs to behave differently depending on the response, you could do something like this:
interface ICallTheService
{
ServiceResponseModel CallTheService();
}
enum ServiceResponseModel
{
Success,
PartialSuccess,
FailureCondition1,
FailureCondition2,
// etc...
}
Then you can prime the ICallTheService fake to return each of the possible responses and test your class based on this.
A.CallTo(() => serviceCaller.CallTheService()).Returns(ServiceResponseModel.Success);
For Example if some Exceptions (defined in WCF) are handled correct
This is also nothing to do with business logic. The actual handling of exceptions is the responsibility of the ICallTheService implementation. In fact, I would introduce another class for this, whose job it would be to translate the various possible exceptions from System.ServiceModel into your response model. Eg
class WCFErrorResponseTranslator
{
ServiceResponseModel TranslateWCFException (Exception ex)
{
if (ex.GetType() == typeOf(TimeoutException)) { return ServiceResponseModel.TimeOut; }
/// etc
}
}
This behaviour could then be tested in isolation.
I have two service contracts and they get implemented as one. Naturally, I'm creating two client proxies for those contracts. Is it possible to maintain session between these two proxies. (btw I'm just starting with WCF so cut me some slack if I'm being too dumb)
As an example,
[ServiceContract(SessionMode = SessionMode.Required)]
public interface IFoo
{
[OperationContract]
void DoFoo(int something);
}
[ServiceContract(SessionMode = SessionMode.Required)]
public interface IBoo
{
[OperationContract]
int DoBoo();
}
[ServiceBehavior(InstanceContextMode =InstanceContextMode.PerSession)]
public class myservice: IFoo, IBoo
{
int somevalue;
void DoFoo(int something)
{
somevalue = something;
}
int DoBoo()
{
return somevalue;
}
}
Client Side Code:
using ServiceReference1;
static void main()
{
DoFooServiceClient fooproxy = new DoFooServiceClient();
DoBooServiceClient booproxy = new DoBooServiceClient();
fooproxy.DoFoo(5);
Console.WriteLine(booproxy.DoBoo());
}
I want it to return 5 but it returns 0. I know what's wrong, it is indeed creating two instances but is it possible to force them to use same instance? If I used static wouldn't it be the same value for all clients?
Since WCF instancing operates at the service contract level, you are going to struggle to share memory between only these two services.
Yes you could use a some static type but, as you say, the value would be synchronized across all service instances regardless, which is not the behavior you require.
An option would be to use some persistent resource like a database, or a singleton service instance, to store this shared data.
Another option may be possible, if you were to define Doo and Foo as singleton services for instancing. This would mean that you could access the state of each service directly from the service host, but would require some mediation logic to synchronize values between them.
I will try the mediation logic to sync values but that would require
additional client side code, wouldn't it?
It does not require client side code, but something on the service host to sync values between two service instances. I can only think of a way to do this if the services are both singleton instances. This becomes more complicated if you are using IIS for hosting, as this means you are not exposed to the actual ServiceHost instances.
I need to have a service which would be called from my client project. The requirement is that I can change and release a service but after changing the service there should not be a need to rebuild the client. The example is, suppose I have service which helps s person reach the destination
[ServiceContract]
IDestinationHelper
{
[OperationContract]
void ReachDestination(string person);
}
class ReachedByTrain:IDetinationHelper
{
void ReachDestination(string person)
{
//Help the person to reach destination
}
}
Now the service is helping the person to reach the destination by train, in this case I will be calling the ReachedByTrain service from client, but suppose a requirement comes and I want the person to reach by Flight, in that case how should I proceed without changing or building the client. The functionality should be plugable and client should automatically detect it
class ReachedByFlight:IDetinationHelper
{
void ReachDestination(string person)
{
//Help the person to reach destination
}
}
Please provide any help or reference about how it can be done.
P.S There will be only one mode present to the client at a time. No matter if the client doesn't know about it.
You have multiple ways to reach extensibility.
The interface is fixed in your client. Building code that handles a changing interface is hard and error prone. Don't do that.
So you will need to keep the interface intact and change the internal behaviour of your class.
In your example, your service could return a list of points as a route to the target and a string that notes the transportation mode. Now you can include all sort of transportation modes and return routes for them without changing the interface.
When you add a new possible transportation mode, the client must be notified so it can be presented to the user for example in a ComboBox. That means you need a method in your interface that returns all possible transportation modes. That way, your client can handle new ones without recompile. It can even handle it when you remove modes.
This way your client has a contract and the contract never changes. But your methods can return different things when you rebuild and redeploy your service.
Example:
This contract never changes:
[ServiceContract]
IDestinationHelper
{
[OperationContract]
IEnumerable<Waypoint> ReachDestination(string transportationMode);
[OperationContract]
IEnumerable<string> GetAvailabletransportationModes();
}
IDestinationHelperService : IDestinationHelper
{
public IEnumerable<Waypoint> ReachDestination(string transportationMode)
{
// decide return value by transportation mode. Use a switch statement, dependency injection, IoC containers, whatever you want
}
public IEnumerable<string> GetAvailabletransportationModes()
{
// decide return value by getting all modes from wherever you decided upon above.
}
}
I think you need to have a [ServiceContract] with an [OperationContract] which would take "ModeOfTransport" as a parameter and has a routing logic to create an object of either ReachByTrain or ReachByPlane or ReachByAnything and would call it from within the [OperationContract]. From the client side you can call the [OperationContract] which has the routing logic with the appropriate parameter on hand.
I'm currently designing a REST WVF web service in C# that will be used by an MVC website and just confused about one point. Say I have two methods with signature
public bool IsEmailAvailable(string email address) { ... }
public DbUser GetUser(object id) { ... }
Can I just keep my service interface and implementation as above? Someone has mentioned to me about designing it more like
public IsEmailAvailableResponse IsEmailAvailable(IsEmailAvailableRequest request) { ... }
public GetUserResponse GetUser(GetUserRequest request) { ... }
What are the pros and cons of implementing it each way?
This is someone is a clever guy. Remote interface is very important, the second version is more maintainable. You can can add additional params into Request|Response without breaking changes. This is a message based style.
As for me, even the second version is not good choice. The second version contains too concrete methods. A remote interface should be based on parametric polymorphism, so this kind of API will be stable and flexible
Thus, RESTful api should look like:
object Get(object request);
object Post(object request);
object Put(object request);
object Delete(object request);
etc..
Unfortunately, WCF doesn't support this kind of interface by default, but we can use the Message instead object and get the same result.
Take a look a following article for more details: Building RESTful Message Based Web Services with WCF
I have a simple Fire and Forget service operation that works fine and doesn't block. However, when I try to close the service proxy, it will block until the one-way call completes. Is this expected behavior?
Client Code:
var serviceProxy = new MyServiceProxy();
serviceProxy.OneWayCall();
serviceProxy.Close(); // This blocks until OneWayCall() is finished.
Service:
[ServiceContract]
public interface IMyService {
[OperationContract(IsOneWay = true)]
void OneWayCall();
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class MyService : IMyService {
public void OneWayCall() {
// Stuff and things
}
}
Yes - depending on the binding/configuration your service is using and if you are using sessions in any way. See the below link for information on configurations that lead to blocking:
WCF Best Practice #5: One-way is not always really one-way
Hope that helps
For completeness' sake; here is what Microsoft has to say about this behavior:
Clients Blocking with One-Way Operations