I have written a code for Person class and in that class create a constructor Person and argument name. Now I have to create an instance of this class will offer a getter for the person's name and also create an instance of this class will respond to a greet method that accepts one argument: message.
When the message is "Hello", greet must return:
Hi, I'm {{name}}
When the message is "Goodbye", greet must return:
Bye
When the message is anything else, greet will return the message that it was provided. I have a tested case code but I am stuck with assertEquals() function and getter function. Now I am facing error with assertfunction. Can anybody please tell me how does assertfucntion and getter works? I have implemented getter in my code, I'm but not sure whether I did it right.
Here's my code:
class Person
{
private String name;
Person(String n)
{
n = name;
}
String GetName()
{
return this.name;
}
public void greet(String t)
{
if (t == "Hello")
{
System.out.println("Hi my name is "+name);
}
else if (t == "Goodbye")
{
System.out.println("bye");
}
else
System.out.println("Hi, my name is"+name);
}
}
Test code:
import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.Before;
public class TestPerson {
private Person jeff;
private Person susy;
#Before
public void setup() {
jeff = new Person("Jeff");
susy = new Person("Susy");
}
#Test
public void testGetName() {
assertEquals("Jeff", jeff.GetName());
}
#Test
public void testGreetHelloJeff() {
assertEquals("Hi, I'm Jeff", jeff.greet("Hello"));
}
#Test
public void testGreetHelloSusy() {
assertEquals("Hi, I'm Susy", susy.greet("Hello"));
}
#Test
public void testGreetGoodbye() {
assertEquals("Bye", jeff.greet("Goodbye"));
}
#Test
public void testGreetOther() {
assertEquals("Yo", jeff.greet("Yo"));
}
}
You cannot compare a String and the return value of a method that returns void.
Your Person class is odd. You have it too closely tied to System.out, which is not useful.
Your code has a lot of problems for such a small sample size. Here's what I might suggest:
public class Person {
private String name;
Person(String n) {
this.name = n;
}
String getName() {
return this.name;
}
public String greet(String t) {
if ("Hello".equals(t)) {
return String.format("Hi my name is %s", name);
} else if ("Goodbye".equals(t)) {
return "bye";
} else {
return String.format("Hi, my name is %s", name);
}
}
}
See your method returns void:
public void greet(String t)
How do you expect to get and assert a values of void?
Change void to String and do return a message string.
Also do not use == rather .equals(..)
"Hello" case seems does the same as default. Better do:
public class Person {
private String name;
Person(String name) {
this.name = name;
}
String getName() {
return this.name;
}
public String greet(String m) {
if ("Goodbye".equals(m)) {
return "bye";
} else {
return String.format("Hi, my name is %s", name);
}
}
}
By calling assertEquals("Bye", jeff.greet("Goodbye")); you're comparing the String "Bye" to void since .greet returns void.
Change greet to this:
public String greet(String t){
if(t.equals("Hello"))
return "Hi my name is " + name;
else if(t.equals("Goodbye"))
return "bye";
else
return "Hi, my name is" + name;
}
And then you can use the assertEquals(String, String) like:
assertEquals("bye", jeff.greet("Goodbye"));
In Java when comparing Strings use .equals() instead of ==. So 'if(t=="Hello")"' would be 'if(t.equals("Hello"))'
Method names should start with a lower case letter.
Also String comparison is case sensitive so make sure you are using the correct case when comparing your Strings.
It doesn't make sense to test the greet(String) method using assertEquals, since the method doesn't return anything. The assertEquals is used to assert whether the actual result returned from a tested method is equal to an expected value that you provide, just like the testGetName above.
It seems more appropriate to change void greet(String) to String greet(String) which returns a greeting message according to the t argument to make your code more testable.
Moreover, you should use aStr.equals(bStr) instead of aStr == bStr to compare two String. == just compare the reference of the two String object rather than their values.
Related
Is there any way to format the enum variables when they are called? I mean, If I have the next enum:
public enum Error{
IS_NULL("The variable {NAME_OF_VARIABLE} cannot be null.")
}
So, when I call it I want to replace {NAME_OF_VARIABLE} with the variable which is null. Ex: "The variable {phone_number} is null."
Now I use the next construction:
enum Error{
IS_NULL("The variable {%s} cannot be null.")
public String errorMsg;
}
public String validatePhoneNumber(String phoneNumber){
if(phoneNumber == null){
return String.format(Error.IS_NULL.errorMsg, "phoneNumber")}
return "OK"}
}
}
It works fine, but it looks a bit messy.
Thank you!
Firstly your code doesn't compile and you can make use of a ternary operator to check if the phoneNumber is null or not.
Given the enum :
enum Error {
IS_NULL("The variable {%s} cannot be null.");
public String errorMsg;
private Error(String errorMsg) {
this.errorMsg = errorMsg;
}
}
Validation method can be simplified to
public static String validatePhoneNumber(String phoneNumber) {
return phoneNumber == null ? String.format(Error.IS_NULL.errorMsg, "phoneNumber") : "OK";
}
Using Optional a little cleaner way of doing that could be:
public String validatePhoneNumber(String phoneNumber) {
return Optional.ofNullable(phoneNumber)
.map(a -> String.format(Error.IS_NULL.getErrorMsg(), "phoneNumber"))
.orElse("OK");
}
I've just tried to sign up and am currently on exercise two trying to figure it out. Here it the code.
public class Person {
String name;
public Person(String personName) {
name = personName;
}
public String greet(String yourName) {
return String.format("Hi %s, my name is %s", name, yourName);
}
}
These are the changes I made that seemed to make sense at the time, but I'm still going through it to find what works
public class Person {
String name;
public Person(String personName)
{
name = "John";
}
public String greet(String "Tommy");
{
return String.format("Hi %s, my name is %s", name, yourName);
}
}
If I were to paste this into Eclipse and run it from there is it cheating?
I hope this was clear enough and if there are any ways I can improve this post or make anything clearer please let me know :) thanks!
you just need to swap name and yourName in String.format() function, see the below code
return String.format("Hi %s, my name is %s", yourName, name);
public class Person {
String name;
public Person(String personName) {
name = personName;
}
public String greet(String yourName) {
return String.format("Hi %s, my name is %s", yourName, name);
}
}
Correction and comments in the code below. You will understand everything if you do study some basics of the language otherwise it is going to be fun.
public class Person {
String name;
//This is a constructor and invoked during creation of object
public Person(String personName)
{
//makes no sense to pass personName to construct but, not use it
//name = "John";
name = personName;
}
//A method signature does not end with semi-colon
//You cannot pass string literal in function as argument, "Tommy" incorrect arg
//public String greet(String "Tommy");
public String greet(String greeting)
{
//not sure where you come up with yourName but, i replaced with greeting arg
return String.format("Hi %s, my name is %s", name, greeting);
}
//add main to show you how this works, when run execution enters main first
public static void main(String[] args) {
//an object of Person class is created passing "John" to its constructor
Person p = new Person("John");
//p.greet() invokes the greet method of Person object
System.out.println(p.greet("Oops!"));
}
}
package book1;
import java.util.ArrayList;
public abstract class Book {
public String Book (String name, String ref_num, int owned_copies, int loaned_copies ){
return;
}
}
class Fiction extends Book{
public Fiction(String name, String ref_num, int owned_copies, String author) {
}
}
at the moment when i input values into the variable arguments and call them with this :
public static class BookTest {
public static void main(String[] args) {
ArrayList<Book> library = new ArrayList<Book>();
library.add(new Fiction("The Saga of An Aga","F001",3,"A.Stove"));
library.add(new Fiction("Dangerous Cliffs","F002",4,"Eileen Dover"));
for (Book b: library) System.out.println(b);
System.out.println();
}
}
i get a return value of this:
book1.Fiction#15db9742
book1.Fiction#6d06d69c
book1.NonFiction#7852e922
book1.ReferenceBook#4e25154f
how can i convert the classes to return a string value instead of the object value? I need to do this without changing BookTest class. I know i need to use to string to convert the values. but i don't know how to catch the return value with it. could someone please point me in the right direction on how to convert this output into a string value?
You need to overwrite the toString() Method of your Book class. In this class you can generate a String however you like. Example:
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(this.author).append(": ").append(this.title);
return sb.toString();
}
You need to override the toString() method in your Book or Fiction class. The method is actually declared in the Object class, which all classes inherit from.
#Override
public String toString(){
return ""; // Replace this String with the variables or String literals that you want to return and print.
}
This method is called by System.out.println() and System.out.print() when they receive an object in the parameter (as opposed to a primitive, such as int and float).
To reference the variables in the method, you'll need to declare them in the class and store them via the class's constructor.
For example:
public abstract class Book {
private String name;
private String reference;
private int ownedCopies;
private int loanedCopies;
public Book (String name, String reference, int ownedCopies, int loanedCopies) {
this.name = name;
this.reference = reference;
this.ownedCopies = ownedCopies;
this.loanedCopies = loanedCopies;
}
#Override
public String toString(){
return name + ", Ref:" + reference + ", OwnedCopies: " + ownedCopies + ", LoanedCopies: " + loanedCopies; // Replace this String with the variables or String literals that you want to return and print.
}
}
The classes you have defined, don't store any values. It is in other words useful to construct a new book. You need to provide fields:
public abstract class Book {
private String name;
private String ref_num;
private int owned_copies;
private int loaned_copies;
public String Book (String name, String ref_num, int owned_copies, int loaned_copies) {
this.name = name;
this.ref_num = ref_num;
this.owned_copies = owned_copies;
this.loaned_copies = loaned_copies;
}
public String getName () {
return name;
}
//other getters
}
Now an object is basically a set of fields. If you want to print something, you can access and print one of these fields, for instance:
for (Book b: library) System.out.println(b.getName());
In Java, you can also provide a default way to print an object by overriding the toString method:
#Override
public String toString () {
return ref_num+" "+name;
}
in the Book class.
Need to give your object Book a ToString() override.
http://www.javapractices.com/topic/TopicAction.do?Id=55
Example:
#Override public String toString()
{
return name;
}
Where name, is a string in the Class.
I am hoping that you have assigned the passed arguments to certain attributes of the classes. Now, once you are done with that, you can override the toString() method in Book to return your customized string for printing.
If we create a String like below and print the value:
String s=new String("demo");
System.out.println(s);
...the output is:
demo
Good. This is the expected output. But here String is a class. Remember that. Below is another example. For example, take a class like this:
class A
{
public static void main (String args[])
{
A a =new A();
A a1=new A("hi"); //we should create a Constructor like A(String name)
System.out.println(a1); //here O/P is address
}
}
My doubt is that I created the A instance in the same way I created the new String object, and I printed that object. So why does it not print the given String for the instance of A?
You need to override the Object#toString() in your class. By default, the toString() method of Object is called.
Also, to print the value, you just need to override the method as internally a call will be made to the toString() method when this statement is executed.
System.out.println(a1);
Sample overriden toString() method.
#Override
public String toString() {
// return a string value
return "The String representation of your class, as per your needs";
}
You have to override toString() method in your class the way you want to print something when call System.out.println();. In String class toString() method has override and you will get out put above due to that.
As pointed out already, you need to override the default toString() method inherited from the Object class. Every class automatically extends the Object class, which has a rather simple toString(), which can't know how to turn your particular object into a String. Why should it, especially if your class is arbitrarily complex? How is it supposed to know how to turn all your class's fields into a "sensible" string representation?
In the toString() of your class, you need to return the string that you want to represent your class with. Here is a simple example:
class A {
String foo;
public A(String foo) {
this.foo = foo;
}
public String toString() {
return foo;
}
}
public class sample {
public static void main(String[] args) {
A a = new A("Hello world!");
System.out.println(a);
}
}
String is a class whose purpose is to hold a string value and will return that value if referenced. When you use other classes, you will usually want to add other behavior. If you want to use the class to hold different values that you can set (on object creation or later in processing) you may want to use "setter" and "getter" methods for such values.
Here is an example:
public class Snippet {
private static final String C_DEFAULT_VALUE = "<default value>";
private String name;
private static Snippet mySnippet;
public Snippet() {
}
public Snippet(String value) {
setName(value);
}
/**
* #param args
*/
public static void main(String[] args) {
if (args != null && args.length > 0) {
mySnippet = new Snippet(args[0]);
} else {
mySnippet = new Snippet(C_DEFAULT_VALUE);
}
System.out.println(mySnippet.getName());
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
I wish to achieve the following behavior.
My class under test has a dependency on some other class, I wish to mock this dependency with jMock. Most of the methods would return some standard values, but there is one method, where I wish to make a call to a stubbed implementation, I know I can call this method from the will(...) but I want the method to be called by the exact same parameters that were passed to the mocked method.
Test
#Test
public void MyTest(){
Mockery context = new Mockery() {
{
setImposteriser(ClassImposteriser.INSTANCE);
}
};
IDependency mockObject = context.mock(IDependency.class);
Expectations exp = new Expectations() {
{
allowing(mockObject).methodToInvoke(????);
will(stubMethodToBeInvokedInstead(????));
}
};
}
Interface
public interface IDependency {
public int methodToInvoke(int arg);
}
Method to be called instead
public int stubMethodToBeInvokedInstead(int arg){
return arg;
}
So how do I capture the parameter that were passed to the method being mocked, so I could pass them to the stubbed method instead?
EDIT
Just to give another example, let's say I wish to mock the INameSource dependency in the following (C#) code, to test the class Speaker
public class Speaker
{
private readonly string firstName;
private readonly string surname;
private INameSource nameSource ;
public Speaker(string firstName, string surname, INameSource nameSource)
{
this.firstName = firstName;
this.surname = surname;
this.nameSource = nameSource;
}
public string Introduce()
{
string name = nameSource.CreateName(firstName, surname);
return string.Format("Hi, my name is {0}", name);
}
}
public interface INameSource
{
string CreateName(string firstName, string surname);
}
This is how it can be done in Rhino Mocks for C# I understand it can't be as easy as this since delegates are missing in Java
The solution from Duncan works well, but there is even a simpler solution without resort to a custom matcher. Just use the Invocation argument that is passed to the CustomActions invoke method. At this argument you can call the getParameter(long i) method that gives you the value from the call.
So instead of this
return matcher.getLastValue();
use this
return (Integer) invocation.getParameter(0);
Now you don't need the StoringMatcher anymore: Duncans example looks now like this
#RunWith(JMock.class)
public class Example {
private Mockery context = new JUnit4Mockery();
#Test
public void Test() {
final IDependency mockObject = context.mock(IDependency.class);
context.checking(new Expectations() {
{
// No custom matcher required here
allowing(mockObject).methodToInvoke(with(any(Integer.class)));
// The action will return the first argument of the method invocation.
will(new CustomAction("returns first arg") {
#Override
public Object invoke(Invocation invocation) throws Throwable {
return (Integer) invocation.getParameter(0);
}
});
}
});
Integer test1 = 1;
Integer test2 = 1;
// Confirm the object passed to the mocked method is returned
Assert.assertEquals((Object) test1, mockObject.methodToInvoke(test1));
Assert.assertEquals((Object) test2, mockObject.methodToInvoke(test2));
}
public interface IDependency {
public int methodToInvoke(int arg);
}
Like Augusto, I'm not convinced this is a good idea in general. However, I couldn't resist having a little play. I created a custom matcher and a custom action which store and return the argument supplied.
Note: this is far from production-ready code; I just had some fun. Here's a self-contained unit test which proves the solution:
#RunWith(JMock.class)
public class Example {
private Mockery context = new JUnit4Mockery();
#Test
public void Test() {
final StoringMatcher matcher = new StoringMatcher();
final IDependency mockObject = context.mock(IDependency.class);
context.checking(new Expectations() {
{
// The matcher will accept any Integer and store it
allowing(mockObject).methodToInvoke(with(matcher));
// The action will pop the last object used and return it.
will(new CustomAction("returns previous arg") {
#Override
public Object invoke(Invocation invocation) throws Throwable {
return matcher.getLastValue();
}
});
}
});
Integer test1 = 1;
Integer test2 = 1;
// Confirm the object passed to the mocked method is returned
Assert.assertEquals((Object) test1, mockObject.methodToInvoke(test1));
Assert.assertEquals((Object) test2, mockObject.methodToInvoke(test2));
}
public interface IDependency {
public int methodToInvoke(int arg);
}
private static class StoringMatcher extends BaseMatcher<Integer> {
private final List<Integer> objects = new ArrayList<Integer>();
#Override
public boolean matches(Object item) {
if (item instanceof Integer) {
objects.add((Integer) item);
return true;
}
return false;
}
#Override
public void describeTo(Description description) {
description.appendText("any integer");
}
public Integer getLastValue() {
return objects.remove(0);
}
}
}
A Better Plan
Now that you've provided a concrete example, I can show you how to test this in Java without resorting to my JMock hackery above.
Firstly, some Java versions of what you posted:
public class Speaker {
private final String firstName;
private final String surname;
private final NameSource nameSource;
public Speaker(String firstName, String surname, NameSource nameSource) {
this.firstName = firstName;
this.surname = surname;
this.nameSource = nameSource;
}
public String introduce() {
String name = nameSource.createName(firstName, surname);
return String.format("Hi, my name is %s", name);
}
}
public interface NameSource {
String createName(String firstName, String surname);
}
public class Formal implements NameSource {
#Override
public String createName(String firstName, String surname) {
return String.format("%s %s", firstName, surname);
}
}
Then, a test which exercises all the useful features of the classes, without resorting to what you were originally asking for.
#RunWith(JMock.class)
public class ExampleTest {
private Mockery context = new JUnit4Mockery();
#Test
public void testFormalName() {
// I would separately test implementations of NameSource
Assert.assertEquals("Joe Bloggs", new Formal().createName("Joe", "Bloggs"));
}
#Test
public void testSpeaker() {
// I would then test only the important features of Speaker, namely
// that it passes the right values to the NameSource and uses the
// response correctly
final NameSource nameSource = context.mock(NameSource.class);
final String firstName = "Foo";
final String lastName = "Bar";
final String response = "Blah";
context.checking(new Expectations() {
{
// We expect one invocation with the correct params
oneOf(nameSource).createName(firstName, lastName);
// We don't care what it returns, we just need to know it
will(returnValue(response));
}
});
Assert.assertEquals(String.format("Hi, my name is %s", response),
new Speaker(firstName, lastName, nameSource).introduce());
}
}
JMock doesn't support your use case (or any other mocking framework I know of in java).
There's a little voice in my head that says that what you're trying to do is not ideal and that your unit test might be to complicated (maybe it's testing too much code/logic?). One of the problems I see, is that you don't know which values those mocks need to return and you're plugging something else, which might make each run irreproducible.